statelyai / xstate

Actor-based state management & orchestration for complex app logic.
https://stately.ai/docs
MIT License
26.79k stars 1.23k forks source link

issue with assign - "No implementation found for action type" #220

Closed amelon closed 5 years ago

amelon commented 5 years ago

Bug or feature request?

bug using version 4.0.0-4.0.1.

It worked previously on 4.0.0-13 and 4.0.0-15.

Description:

using assign makes action "invisible".

(Bug) Expected result:

action should be recognized

(Bug) Actual result:

Here result with exemple on context documentation:

No implementation found for action type 'addWater'

Here is the code

const { Machine, actions } = require('xstate')
const { assign } = actions
const { interpret } = require('xstate/lib/interpreter')

// Action to increment the context amount
const addWater = assign({
  amount: (ctx, event) => ctx.amount + 1
})

// Guard to check if the glass is full
function glassIsFull(ctx, event) {
  return ctx.amount >= 10
}

const glassMachine = Machine({
  id: 'glass',
  // the initial context (extended state) of the statechart
  initial: 'empty',
  states: {
    empty: {
      on: {
        FILL: {
          target: 'filling',
          actions: 'addWater'
        }
      }
    },
    filling: {
      on: {
        '': {
          target: 'full',
          cond: 'glassIsFull'
        },
        FILL: {
          target: 'filling',
          actions: 'addWater'
        }
      }
    },
    full: {}
  }
})

const int = interpret(glassMachine.withConfig({
  actions: { addWater },
  guards: { glassIsFull }
}).withContext({
    amount: 0
  }))

int.onEvent((...args) => console.log(args))
int.start()

int.send('FILL')

You can find code here.

davidkpiano commented 5 years ago

The fix is in master and will be in the next release. This is related to #195

simlrh commented 5 years ago

Hi @davidkpiano, using master the error is now No implementation found for action type 'xstate.assign'

davidkpiano commented 5 years ago

@simlrh - Just pushed, can you pull and try again now?

davidkpiano commented 5 years ago

Important to note here too that trying to directly send an assign action...

service.send({ type: 'xstate.assign', ... })

will (probably) produce the same warning and have no effect. This is on purpose; assignment should be done through actions (i.e., part of your statechart) rather than events (which is more of an imperative approach) otherwise it defeats the purpose of the statechart, as anything can change at any time.

simlrh commented 5 years ago

Yes, seems to be the expected result now, thank you very much. Regarding sending assignments as actions rather than events - the original reporter's code listing is doing it the correct way, is that right?

davidkpiano commented 5 years ago

Yes, it's correct, because assign is done through actions.

davidkpiano commented 5 years ago

Closing as this is fixed in master