0

When using x state app machine. How do I set the initial state to a variable? I want the intial state to be either full screen or menu, when the boolean value is sent from another file. I want to send a boolean value from some page to the app machine, and change the initial state based on that value.

VIDEO MACHINE

{
  id: "interactiveVideoMachine",
  context: {
    useFullscreenDefault: false,
  },
  user: {
    id: "user",
    initial: `${useFullscreen ? "fullscreen" : "menu"}`, // <--here
    states: {
      menu: {/*...*/},
      fullscreen: {/*...*/},
    },

    on: {
      SET_FULLSCREEN_DEFAULT: {
        actions: "setFullscreenDefault",
      },
    },
  },
};
{
  actions: {
    setFullscreenDefault,
  },
};

ASSIGN ACTION

const setFullscreenDefault: AssignAction<
  InteractiveVideoContext,
  InteractiveVideoEvent
> = actions.assign({
  useFullscreenDefault: (ctx, event) => event.useFullscreenDefault,
});

SVELTE FILE

let isFullscreenDefault: boolean;

const handleFullScreenDefault = () => {
  console.log(isFullscreenDefault); //log here
  if (interactiveVideoStateService) {
    interactiveVideoStateService.send({
      type: "SET_FULLSCREEN_DEFAULT",
      isFullscreenDefault,
    });
  }
};
Daniel
  • 34,125
  • 17
  • 102
  • 150
lache
  • 608
  • 2
  • 12
  • 29
  • Can you give more contextual details about what you want to accomplish? Also, what kind of process or user interaction sets the boolean value in the first place? I guess, you could have an initial state `'uninitialized'` and send to different kinds of events depending on the boolean value. if true -> `.send(type: "SET_FULLSCREEN")`. if false -> `.send (type: "SET_MENU")`. – Tobi Obeck Mar 30 '23 at 18:10
  • I set a on/off boolean value as a sort of “flag” to turn whether the page is full screen by default or not full screen(menu version). I manage the state of the page however through xstate. So in my mind I’m thinking well I just need to send that Boolean value to xstate, and from there, change the initial state based on that value I sent. Because I want the first state to be determined by the value I get from that flag. – lache Mar 31 '23 at 20:39

1 Answers1

1

When it comes to setting initial values, I am usually using a machine factory function:

function createInteractiveVideoMachine({
  useFullscreen,
}: {
  useFullscreen: boolean;
}) {
  return createMachine({
    id: "interactiveVideoMachine",
    states: {
      user: {
        id: "user",
        initial: `${useFullscreen ? "fullscreen" : "menu"}`, // <--here
        states: {
          menu: {
            /*...*/
          },
          fullscreen: {
            /*...*/
          },
        },
      },
    },
  });
}

Then use it like so:

let isFullscreenDefault: boolean;
const { state, send } = useMachine(createInteractiveVideoMachine({useFullscreen: isFullscreenDefault}));
z_lander
  • 104
  • 1
  • 8