Hyperapp: Pass parameters to effects functions?

Created on 8 Feb 2017  路  11Comments  路  Source: jorgebucaran/hyperapp

I am trying to build a simple login form with hyperapp. You are either already logged in, in which case you get a link to log out, or you are not logged in, in which case you get a username/password form.

Now to do the actual authentication of the username & password via the backend, I need to use an effect (asynchronous operation). But since effects don't take any parameters (as per the docs), and only have access to the model, that means I need to store the currently input username & password in my model. To achieve this, I must use reducers bound to oninput in each field. Just so I know i have the latest input value available to the login-effect, when it is called (in the onsubmit event of the form tag)

Two problems with this, that the ability to pass parameters to effects (just like you can for reducers), would solve:

1) What the user types in the input & password fields is a temporary state. Those slots in the model aren't relevant once the user has logged in, and it seems wasteful to allocate space in the model for something that will only be relevant before the user is logged in. (And if they are already logged in, those slots will never be used)

2) I don't really need the username/passwords in the model for any other reason. I'm just using the model to carry the values into the login-effect. So it seems a waste of computing power to have to update the model every time a key is typed, when all i really care about is what the values of the fields are at the time the user presses submit.

Docs

Most helpful comment

@jbucaran: nope nothing else :) That's perfect. It was the fact that data was missing from the effect function signature that was throwing me. It's there now and all is well :)

All 11 comments

But since effects don't take any parameters (as per the docs)

That's not true. Every action can be passed with arguments, actually single data argument, through the views. It is easy as msg.action(data). If you want to call other effect from some effect you can do it too.

app({
  effects: {
    foo: (model, msg, data, done) => {
      msg.bar({ bar: data.bar + model.bar + ' from foo' })
    },
    bar: (model, msg, data, done) => console.log(data)
  }
})

Ah, so I can pass data to effects -- that's great news! But the docs should really reflect this (they mention data for update-reducers but not effects).

Yep, we should make the docs better, definitely, haha.

@tunnckoCore what does done do?

@dodekeract done is that error. it is just options.onError function and it throws given error by default, but you can change this behaviour.

It is just common to call such arguments next, done, cb and etc

edit: because it kinda "follows" the node's "error first callbacks" convention - cb(err).

Let's say you have this

'use strict'
const { app, html } = hyperapp

app({
  model: {
    text: 'init'
  },
  view: (model) => html`<h1>${model.text}</h1>`,
  hooks: {
    onError: (err) => console.log('huh, err!', err.message) 
  },
  update: {
    first: (model, data) => ({ text: data.text + ' reducer' })
  },
  effects: {
    foo: (model, msg, data, cb) => {
      msg.first({ text: data.text + 'effect '})
      msg.bar({ text: data.text + model.text + ' from foo' })
        .then((message) => {
          throw new Error(message)
        })
        .catch(cb)
    },
    bar: (model, msg, data) => {
      return new Promise((_) => {
        resolve(data.text + 'bar')
      })
    }
  },
  subs: [
    (model, msg) => msg.foo({ text: 'on load ' }) 
  ]
})

@zaceno It's hard to find, but it's there. I think I can improve this bit of the docs by adding a note to the effects section in the README. Thanks for pointing it out.

screen shot 2017-02-09 at 11 13 45

in addition to the screenshot: _"where data is any data you want to pass to the action which is reducer / effect"_

@tunnckoCore Good point, will fix!

@zaceno Docs have been updated. See https://github.com/hyperapp/hyperapp#effects

Let me know if that's good enough or we need to address anything else.

@jbucaran: nope nothing else :) That's perfect. It was the fact that data was missing from the effect function signature that was throwing me. It's there now and all is well :)

Was this page helpful?
0 / 5 - 0 ratings