Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How do you initialize a store with data? #1

Closed
willcosgrove opened this issue Jan 7, 2015 · 10 comments
Closed

How do you initialize a store with data? #1

willcosgrove opened this issue Jan 7, 2015 · 10 comments

Comments

@willcosgrove
Copy link

I've looked through your examples, but I haven't found a way to populate a store with existing data. I see you set values in the constructor, but the values are always hard coded.

I'm interested in something like this:

class ProjectStore {
  constructor(value) {
    self.value = value
  }
}

alt.createStore(ProjectStore, {foo: "Bar"})

Is this something that's planned, or is there a preferred way of achieving this same effect?

By the way, awesome job with Alt, I'm really liking it over some of the other Flux implementations I've tried!

@goatslacker
Copy link
Owner

Good question. There are three ways to set a store's data in alt, and just two according to flux.

For flux

  • In the constructor itself
  • Through actions

For Alt you can use the methods above as well as

  • Using bootstrap

In your particular example since you already know the value of foo you can just set it in the constructor. However, the constructor approach isn't terribly useful since, most likely, your data lives in some storage that is asynchronous. So that leaves us with just actions and bootstrapping. In flux, since the data flow is unidirectional, all updates to the store should solely come from the actions.

A common pattern is to kick off a few actions at startup time to seed the stores with data, you can see an example of that in flux-chat. Since this is a pretty common pattern alt has this special method called bootstrap which seeds all your stores with some initial data. I don't have any examples showing off asynchronous data loading just yet, but they're coming soon.

To answer your question though, you can do something like:

alt.bootstrap(JSON.stringify({
  ProjectStore: {
    foo: "Bar"
  }
})

and an async example:

getFooValueFromServer().then(function (fooValue) {
  alt.bootstrap(JSON.stringify({
    ProjectStore: {
      foo: fooValue
    }
  })
})

Disclaimer: bootstrap only works once, it's meant to be used on initialization and then never again.

@willcosgrove
Copy link
Author

Thanks for the reply! I ended up going with a global initialDataLoad Action that all the stores listened for. Works perfectly!

@steffenmllr
Copy link

I'm also trying to wrap my head around this.

Since everything is a singleton in flux what, is there a way to pre-render the app on the server (let's say with something like react-router) and some async data (some api call) ?

The only solution I found so far is yahoos fluxible but I really like the ES6 syntax of alt.

Is it possible to do a real isomorphic with alt?

@goatslacker
Copy link
Owner

@steffenmllr check out this example https://github.com/goatslacker/iso/tree/master/examples/react-router-flux

It uses react-router and alt.

The idea is that you fetch all your data on the server, once all the data is gathered you bootstrap it, and then you bootstrap back on the client.

I'm still experimenting with the API as you can see in this commit so if you plan on using this example verbatim then make sure to use version 0.7.0

npm install alt@0.7.0 --save

Let me know at a high level how you're planing on fetching the data and using this, I'm gathering as much data as possible before I solidify the API for a 1.0.0 release.

@steffenmllr
Copy link

Thanks for the example. As I'm new to the flux concept, let me play with it and see how and if it works.
Wouldn't it be better to create a new alt instance on each request and than bootstrap it?

On a higher level, i would like to define the routes once (I can figure that out) and maybe also share the api calls (I can figure that out too).

The only thing I would like to see is easy server side based rendering :)

@goatslacker
Copy link
Owner

Creating an instance is the solution that fluxible came up with. The tradeoff with that is that you'll be giving up CommonJS require in favor of dependency injection since you'll need to inject the instance into all your React components and pass down the instance through the children, this can get quite messy.

The other problem with the instance approach is that then you'll start to use actions on the server. While this isn't a big deal in itself and can be manageable the logic can get hairy.

Actions are meant to be fire and forget, it's easy to track when one action finishes because you can listen to its corresponding store. However, you're limited to calling one action on the server because otherwise you can't keep track of when all actions have finished dispatching unless you do manual book-keeping.

The current tradeoff with alt is that you do all the data fetching yourself and then bootstrap the store. Pretty soon, I'll be creating an example where some of the data fetching is isomorphic as well.

If you can, share some of the api calls you're planning on making isomorphic so I can get a better idea of how you're trying to architect and we can massage alt's API.

@steffenmllr
Copy link

Thanks for the insights. I think the problem is, that flux isn't really designed to work on the server and client. Using actions on the server is not really an option since you would have to register all the events and callbacks somewhere and keep track of them (as you said).

If I only use one alt singleton instance you state in the docs that I can only use bootstrap once. In the example you use it on per request basis. Can you tell me whats the difference between boostrapping on the server and on the client ?

The app my building is pretty "dumm". There is only client side CRUD Logic and the whole thing only talks to a REST API.

@goatslacker
Copy link
Owner

"Dumb" apps are interesting to me because that's what is most often being built so easing the pain of the 80% use case is something that concerns me.

Per alt 0.7.0, bootstrap on the server allows you to bootstrap the state and then immediately rolls-back to its initial state. Since this is a synchronous operation you're allowed to render your views with the proper state before the store's state resets on the next cycle. It's not perfect but its a trade off. On the client side you're only allowed to bootstrap once.

I'm thinking of changing this to allow you to bootstrap always on the client and adding back a special bootstrapFromServer (name pending) method that does the magic.

goatslacker pushed a commit that referenced this issue Oct 22, 2015
Add check for Object.isFrozen() in isPojo()
@sjatkins
Copy link

sjatkins commented Aug 15, 2016

I do not understand where the bootstrap should be. In my app I have one critical store I would like to initialize early. Do I invoke an action and put the bootstrap into that? If so then where should that action be invoked from?

And if you will please do not assume isomorphic server side React rendering as that only increases complexity.

@jdlehman
Copy link
Collaborator

@sjatkins You can put bootstrap anywhere in your code after you have initialized alt. (you do not need to invoke an action, you can just call it on the initial load of your app. So once you have an instance of alt:

// bootstrap expects stringified json
alt.bootstrap(JSON.stringify(jsonData));

where jsonData is JSON in the structure:

{
  StoreName: {
    key: value,
    key2: value2
  },
  StoreName2: {
    key: value,
    key2: value2
  },
}

you might get this data from a call to your server like in the async example above or from localStorage. bootstrap docs

prcolaco pushed a commit to decentrawise/alt that referenced this issue Mar 7, 2024
upgrade node to v16, and update dependencies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants