Giter Site home page Giter Site logo

Comments (14)

tomkis avatar tomkis commented on May 24, 2024 1

it just returns the return value not an iterable. i probably miss something.

No you are not, sorry my bad, I overlooked the yield* keyword. You'r right that will work.

to you mind to show me how this would look like? if i define the fetchGif effect in randomGif module how can i reuse/compose it in randomGifList with redux-saga-rxjs. or is this ATM not possible.

You can actually check history of the repo https://github.com/salsita/redux-elm/blob/v0.3.0/examples/src/6-list-of-random-gif-viewers/main.js#L58 the composeSaga function does the trick, though the implementation is wrong and does not work for all use cases.

Saga composition is indeed really hard to achieve but doable. Anyway, we've decided to go the Generators way, at least for 1.x

from prism.

tomkis avatar tomkis commented on May 24, 2024

There are two benefits:

  1. Elm provides type safety so you'll get much more compiler information when something doesn't work - it works especially well with the Elm Architecture
  2. There are no runtime errors in Elm

Generators are not necessary unless you need side effects and even simple applications need side effects, for example API communication, logging, caching etc. https://github.com/salsita/redux-side-effects - This package allows us to reduce side effects using generators... Basically any function yielded within reducer is not immediately executed, instead its execution is deferred and dispatch is provided -> this is basically same approach which Elm is using, but Elm is using declarative effects which are reduced as well, therefore Elm's updater returns Pair<Model, Effects> and we emulate the same by using yield for emitting thunks (side effects) and the returned value is just plain old mutated Model.

from prism.

anler avatar anler commented on May 24, 2024

@faceyspacey maybe you'll like olmo though I need to port all the examples

from prism.

minedeljkovic avatar minedeljkovic commented on May 24, 2024

To achieve a variation of benefit 1), in our project, we use excelent tcomb library, similar to how it is done in tcomb-redux. It follows composition of state and actions nicely. @tomkis1, I can do a PR here, if you are interested to see how it fits with examples.

We started the project about two months ago, and came up with almost identical redux aditions as you implemented here (forwardTo, mapEffects), which is no coincidence since we also wanted to port critical parts of Elm architecture to Redux and are using your redux-side-effects. :) So far we are very satisfied how it grows around such architecture.

from prism.

tomkis avatar tomkis commented on May 24, 2024

@minedeljkovic I am really glad that we are sharing the view.

To achieve a variation of benefit 1), in our project, we use excelent tcomb library, similar to how it is done in tcomb-redux. It follows composition of state and actions nicely. @tomkis1, I can do a PR here, if you are interested to see how it fits with examples.

I was something about something less intrusive Flow? TypeScript? Yet I am more inclined to Flow as it's babel friendly.

We started the project about two months ago, and came up with almost identical redux aditions as you implemented here (forwardTo, mapEffects), which is no coincidence since we also wanted to port critical parts of Elm architecture to Redux and are using your redux-side-effects. :) So far we are very satisfied how it grows around such architecture.

Frankly, we are getting more and more skeptical about Generators as using them has its drawbacks. You can't use callbacks because yield* is not automatically propagated which is a showstopper for example when using something like immutable.js.

So my long term idea is think about Elmish composability of sagas using https://github.com/salsita/redux-saga-rxjs and avoid side effects in reducers at all. Also, I would rather avoid nesting actions. Instead, the composition would be done via action naming so that we can do easy pattern matching. Action would be something like

{
  type: 'COUNTERS.TOP.INCREMENT',
  payload: 1
}

from prism.

tomsdev avatar tomsdev commented on May 24, 2024

@tomkis1 could you explain why pattern matching on the action name is better than nesting actions in your opinion?
I wonder if there is a difference in performance also when you want to check for a "match".

from prism.

tomkis avatar tomkis commented on May 24, 2024

@tomsdev it's possible to use regexp for pattern matching with plain old strings so it allows us more advanced matching. Also, unwrapping is easy because there's no need to recursively access the action.payload.payload.payload...

from prism.

namjul avatar namjul commented on May 24, 2024

@tomkis1 in which way do you think immutable.js is incompatible with redux-side-effects? can you give an example of a situation in which i need to yield inside a immutable.js callback.

from prism.

tomkis avatar tomkis commented on May 24, 2024

@namjul imagine following:

function* updater(immutableAppState) {
   return immutableAppState.map(item => {
       yield ApiSideEffect();

       return item.set('loading', true);
   });
}

This simply doesn't work and it doesn't work with anonymous generator as well.

function* updater(immutableAppState) {
   return yield* immutableAppState.map(function*(item) {
       yield ApiSideEffect();

       return item.set('loading', true);
   });
}

does not work either.

from prism.

namjul avatar namjul commented on May 24, 2024

right thx.
but wouldn't the following work:

function* item(item) {
       yield ApiSideEffect();

       return item.set('loading', true);
}

function* update(immutableAppState = Immutable.Map(), action) {
        return immutableAppState.set(action.id, yield* item(state.get(action.id), action))
}

probably there are still situations you need an yield directly in the map callback.

In your next branch i saw that you couple redux-elm with redux-side-effects.
What i would like is to use your redux-elm action-pattern-routing solution + redux-loop to solve the problem with immutable.js.
Is there a way we can use these seperatly?

from prism.

namjul avatar namjul commented on May 24, 2024

so i tried it and build the randomGifList with immutable.js without using map:

.case(name, function*(state, action, randomGifId) {
    return state.setIn(['gifList', randomGifId], yield* mapEffects(randomGif.reducer(state.getIn(['gifList', randomGifId]), action), name, randomGifId))
}, Matchers.parameterizedMatcher)

from prism.

tomkis avatar tomkis commented on May 24, 2024

@namjul

but wouldn't the following work:

function* item(item) {
       yield ApiSideEffect();

       return item.set('loading', true);
}

function* update(immutableAppState = Immutable.Map(), action) {
        return immutableAppState.set(action.id, yield* item(state.get(action.id), action))
}

It would not, because your item function is generator and calling generator returns iterable therefore it would only set iterable into the App state.

probably there are still situations you need an yield directly in the map callback.

There's (or should be) a workaround by allowing yielding array of effects, that way you could map effects using traditional map function and then yield the result.

In your next branch i saw that you couple redux-elm with redux-side-effects.
What i would like is to use your redux-elm action-pattern-routing solution + redux-loop to solve the problem with immutable.js.
Is there a way we can use these seperatly?

For now, it looks like we will lock this repo with Generators because redux-loop seemed too awkward for us to use, there's an alternative project which is doing that though https://github.com/jarvisaoieong/redux-architecture

so i tried it and build the randomGifList with immutable.js without using map:

Yes that's definitely a solution, however you have to realize that with redux-elm you will most like won't even need immutable js because entire application state is nicely sliced into smaller chunks and spread operator serves pretty well here.

from prism.

namjul avatar namjul commented on May 24, 2024

yes, i can see that immutable.js is likely not needed with redux-elm.
i am still confused why the first example would not work. Its similar to the second example and it works.
yield* would just return the return statement from the item generator function. Which would be an immutable.js object...

function* anotherGenerator(i) {
  yield i + 1;
  yield i + 2;
  yield i + 3;
  return 2;
}
function* generator(i){
  yield i;
  console.log(yield* anotherGenerator(i));
  yield i + 10;
}
var gen = generator(10);

console.log(gen.next().value); // 10
console.log(gen.next().value); // 11
console.log(gen.next().value); // 12
console.log(gen.next().value); // 13
// 2
console.log(gen.next().value); // 20

it just returns the return value not an iterable. i probably miss something.

So my long term idea is think about Elmish composability of sagas using https://github.com/salsita/redux-saga-rxjs and avoid side effects in reducers at all.

to you mind to show me how this would look like? if i define the fetchGif effect in randomGif module how can i reuse/compose it in randomGifList with redux-saga-rxjs. or is this ATM not possible.

from prism.

tomkis avatar tomkis commented on May 24, 2024

Closing this issue in favour of #5

from prism.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.