Hi there,
And welcome to our community
.
I’d suggest to do the following:
- Define your change event to include both the measurement type, e.g.
rotationCount
or temperature
and the corresponding value
- Implement a fish to listen to these events and compute its state which would be simply a map of measurement types to the last value
- Use that fish in your React app (
useFish()
) and wire the separate map entries of the state to rows in your table.
Fish incl. event type declaration
import { FishId, Fish, Tag } from '@actyx/pond'
// (1) Measurement event type
export type Measurement = 'rotationCount' | 'temperature' | 'incomingVoltage'
export type MeasurementEvent = {
sourceMachine: string,
measurement: Measurement,
value: number
}
type LastMeasurementState = {}
export const measurementTag = Tag<MeasurementEvent>('Measurement')
export const LastMeasurementsFish: Fish<LastMeasurementState, MeasurementEvent> = {
fishId: FishId.of('ax.example.community.78', 'LastMeasurementFish', 0),
initialState: {},
onEvent: (state: LastMeasurementState, event: MeasurementEvent) => {
state[event.measurement] = event.value // (2) only record the last measurement
return state
},
where: measurementTag,
}
UI Component
import * as React from 'react'
import { useFish } from '@actyx-contrib/react-pond'
import { LastMeasurementsFish } from './fish/LastMeasurementsFish'
export const Foo = (): JSX.Element => {
const measurements = useFish(LastMeasurementsFish)
return (
<table>
<thead>
<tr>
<th>Measurement</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<!-- (3) -->
{
Object.keys(measurements.state).map((k) => (
<tr key={k}>
<td>{k}</td>
<td>{measurements.state[k]}</td>
</tr>
))
}
</tbody>
</table>
)
}
Note that this example does only record the latest measurement of each type, not the latest measurement per machine of each type. If you require this, you can simply extend onEvent
to produce the desired state.
Here’s the component with additional controls to emit measurement events, in case you want to play with it in isolation.
import * as React from 'react'
import { useState } from 'react'
import { usePond, useFish } from '@actyx-contrib/react-pond'
import { LastMeasurementsFish, measurementTag } from './fish/LastMeasurementsFish'
export const Foo = (): JSX.Element => {
const [measurement, setMeasurement] = useState('temperature')
const [value, setValue] = useState(-1)
const measurements = useFish(LastMeasurementsFish)
const pond = usePond()
return (
<div>
<table>
<thead>
<tr key={k}>
<th>Measurement</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td><input onChange={({ target }) => setMeasurement(target.value)} value={measurement} /></td>
<td><input onChange={({ target }) => setValue(target.valueAsNumber)} value={value} type='number' /></td>
</tr>
{
Object.keys(measurements.state).map((k) => (
<tr>
<td>{k}</td>
<td>{measurements.state[k]}</td>
</tr>
))
}
<tr>
<td colSpan={2}>
<button onClick={() => {
pond.emit(measurementTag, {
sourceMachine: 'M1',
measurement: measurement,
value: value
})
}}>measure</button>
</td>
</tr>
</tbody>
</table>
</div>
)
}
Does this help? Feel free to ask, if you have further questions.