menu
announcement

Spectrum is now read-only. Learn more about the decision in our official announcement.

Statecharts

The Statecharts community on Spectrum is (along with spectrum) MOVING TO OTHER PLATFORMS: For statecharts discussions in general go to Statecharts Discussion on GitHub (link) or Gitter (link). For XState-specific questions, go to the XState discussion forum for Q&A or the Stately discord chat to chat.

Channels
Team

Update context from an activity?

July 10, 2019 at 1:35pm

Update context from an activity?

July 10, 2019 at 1:35pm
Is is possible to update the machines context from inside an activity:
Below is a simple example just for illustration.
const toggleMachine = Machine( { id: 'toggle', context: { count: 0 }, initial: 'inactive', states: { inactive: { on: { TOGGLE: 'active' } }, active: { // The 'beeping' activity will take place as long as // the machine is in the 'active' state activities: ['beeping'], on: { TOGGLE: 'inactive' } } } }, { activities: { beeping: () => { // Start the beeping activity const interval = setInterval(() => console.log('BEEP!'), 1000); assign({ count: context.count + 1 }) // Return a function that stops the beeping activity return () => clearInterval(interval); } } } );

July 10, 2019 at 2:14pm
Activities (in general statechart terminology) are "fire-and-forget" effects, which means they are executed but do not communicate back to the machine. See effects for a better explanation.
You might want to invoke a service instead.
I have a websocket listener that I am running inside the activity, and when it receives an update I want to update the context.
How would you advise would be the best way to go about this?
Invoke a websocket machine, which might look something like this:
import { actions, sendParent, Machine } from 'xstate';
const websocketMachine = Machine({
id: 'retry',
initial: 'active',
states: {
active: {
invoke: {
src: _ => cb => {
const socket = new WebSocket('ws://localhost:12345');
socket.addEventListener('message', e => {
const jsonData = JSON.parse(e.data);
cb({ type: 'WS.EVENT', data: jsonData });
});
socket.onclose = err => {
cb(actions.error(err, 'websocket'));
};
},
onError: 'willRetry'
},
on: {
'WS.EVENT': { /* do something - assign to context, etc. */ }
}
},
willRetry: {
after: { 2000: 'active' }
}
}
});
like-fill
3
Thanks, that helps

December 7, 2019 at 11:36pm
I have the following application framework:
...Index:
> Component 1 (state machine 1)
> Component 2 (state machine 2)
> Component 3 (state machine 3)
> Component 4 (state machine 4)
...Socket machine
How can I make the Socket state machine listen to the socket and send an event to update the current component data?

December 8, 2019 at 2:43pm
It needs references to the other machine services in order to do that. Can't help if you don't send the full code.

December 29, 2019 at 9:17pm
Could you explain the flow of how to use the activities to listen to the socket and update the context? I did not understand.
See if I'm right: I use an activity to listen to the socket, does this activity on receiving a socket update call a state machine that updates the context?
Don't use an activity. Please see my first post above.
How did you put the socket in your code? Can you give me an example of the configuration of your machine? I did not understand why to call another machine to the socket and the initial state of the application is different. I just want to listen to the socket and update the status of the parent machine or child machines.