martyjs / marty

A Javascript library for state management in React applications
http://martyjs.org
MIT License
1.09k stars 76 forks source link

Fetch never calls done handler #88

Closed orangeloop closed 9 years ago

orangeloop commented 9 years ago

Maybe I'm misunderstanding what should be happening, but it doesn't look to me like the done handler is getting called when the data is fetched asynchronously in remotely. Here's a Plunker that reproduces it:

http://plnkr.co/edit/DKQ6nriYimZ4KeYJCrLc?p=preview

It seems to be an issue when remotely returns the http promise, which then resolves and sets the state (simulated with a setTimeout). The only handler that gets called is pending.

jhollingworth commented 9 years ago

Hey, good question!

The fetch result represents the status of that fetch at that time. You need to re-call getAll once the store has updated.

store.addChangeListener(function () {
  whatever(store.getAll());
});

whatever(store.getAll());

function whatever(users) {
   users.when({
      pending: function () { output.append('pending'); },
      failed: function (error) { output.append('failed: ' + error); },
      done: function (result) { output.append('done: ' + result); }
  }); 
}

If store.addChangeListener doesn't fire you might need to call this.hasChanged() although it should be fired automatically if the state is a different reference.

Does that make sense?

orangeloop commented 9 years ago

It does, thanks for the clarification. I started stepping through the code last night and that's what I was starting to realize. For some reason I was expecting the when handlers would get called anytime the state changed, but I think that's because I was looking at the React examples (where render automatically gets called after the state changes), but I'm implementing in an Angular application.

I ended up wrapping it in a callback like your example and it's mostly working as expected - I'm seeing the callback get called twice for pending. I think it's because remotely loads the data, then calls an action, which the store is listening for, which then updates the state, causing this.hasChanged() to be called - meanwhile, the fetch calls locally again and calls this.hasChanged(), causing the callback to get called twice.

jhollingworth commented 9 years ago

ah yeah, if you have a source action creator which is actually adding the state to the store then you don't need to call this.hasChanged() again.