question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

connect helper for Ember.Service

See original GitHub issue

We just played with our first integration of Redux into Ember (thanks @toranb for your awesome efforts here!), but did something probably quite non-ideomatic: we used the Redux store to manage the state of one central service, not of the overall application.

I used a (just slightly) modified version of connect to bind CPs and actions to a service, rather than a component. Apart from our specific reasons to do that, would you consider this a useful addition to this addon in general?

If so, I could work on a PR for that (cleaning this up and remove code duplication)!

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Comments:6

github_iconTop GitHub Comments

1reaction
simonihmigcommented, Aug 5, 2017

Hey @toranb, first of all thanks a bunch for walking me through this and giving that thorough feedback, highly appreciated! 👍

I stumbled upon reselect before when exploring the redux ecosystem a bit, and my initial thought was that this could indeed be an alternative way to implement my “derived state” use case, but in a bit less ember-ish and more redux-ish way. Good to have this feeling confirmed!

I guess I have to let this sink in a bit, and get more used to it. So when going all in into the redux way, there is probably indeed no need for state CPs on services. But should I discover some good use cases I will certainly share my thoughts with you!

Thanks again for your time!

0reactions
toranbcommented, Aug 5, 2017

Without any additional context I’ll take a run at this but let me know if anything below isn’t clear/or helpful 😃

Above you mentioned defining readonly computed properties on a service that reflect the (redux) store’s state. In ember-redux we create derived state like this using reselect. With reselect you define “selectors” that remind me a lot of computed properties in ember*. I use “selectors” to compute state for my container components. The advantage of reselect (like ember CPs) is that they are cached (taking advantage of memoization). So if the redux state we use to compute a given “selector” hasn’t changed… we don’t re-compute this derived state for components.

To better illustrate this I’ll use an example from the ember-redux guides source. We have a normalized data structure for restaurant => reviews (one-to-many relationship).

The simplified restaurant(s) data structure

{
  '1': {name: 'taco', reviews: [1, 2, 3]},
  '2': {name: 'salad', reviews: [4, 5]},
  '3': {name: 'yum', reviews: []},
}

The simplified reviews data structure

{
  '1': {comment: 'horrible', rating: 1},
  '2': {comment: 'great', rating: 5},
  '3': {comment: 'good stuff', rating : 5},
}

To compute the reviews for a given restaurant we would construct a selector called getReviews

const all = state => state.restaurants.all;
const selectedId = state => state.restaurants.selectedId;
const reviews = state => state.restaurants.reviews;

export const getSelectedRestaurant = createSelector(
  all,
  selectedId,
  (all, selectedId) => all[selectedId]
);

export const getReviews = createSelector(
  reviews,
  getSelectedRestaurant,
  (reviews, selectedRestaurant) => {
    return selectedRestaurant.reviews.map(reviewId => {
      return reviews[reviewId];
    });
  }
);

To answer the second part of your question “is there a good reason to not have the state as a CP on the redux service itself” This is handled for you when you define container components using the connect api. Behind the scenes stateToComputed will construct a readonly computed property on the component for you that simply returns the (redux) state/or reselect value.

import { connect } from 'ember-redux';
import { getReviews } from '../reducers/restaurants';

var stateToComputed = (state) => {
  return {
    reviews: getReviews(state)
  };
};

export default connect(stateToComputed)();

So in the example above ^^ you would then have access to reviews in your handlebars template. You are able to do this because connect wires up an ember computed property on the fly for each key you return from the stateToComputed function.

If you spend a little time with this approach it’s my hope that you will conclude 1) you no longer need a service for CPs in addition to the ember-redux service provided and 2) leaning on the connect api will provide the readonly CPs you then yield to presentation components with DDAU in mind.

If I’ve got it all wrong or you have a use case I’ve not considered please reach out 😃

*Note: one “gotcha” with reselect is that selectors are not lazy evaluated like computed properties

Read more comments on GitHub >

github_iconTop Results From Across the Web

Helper Functions - Components - Ember Guides
We define helper functions in the app/helpers folder. In this case we want a helper function that takes three arguments: a string, a...
Read more >
buschtoens/ember-service-helper - GitHub
Simple template helper to inject services into templates - GitHub - buschtoens/ember-service-helper: Simple template helper to inject services into ...
Read more >
How to inject service to helper after a promise has been fulfilled?
I just found a 'solution'. I am recomputing the helper every time the 'locales' property changes. This is how my helper looks now:...
Read more >
Helpers and Utilities - Ember Observer
ember -helpers-render-component - Ember Helper that allows you to render a component by specifying the component's name. Any parameters bound to the helper...
Read more >
ember-service-function-helper - npm package - Snyk
ember -service-function-helper · Pass service functions like closure actions into components. For more information about how to use this package see README.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found