Reusable ember component with its own data source - javascript

I have a dropdown <select>-based component that I'd like to be able to drop into any template in the hierarchy of my ember app.
This displays a list of all the Articles (the model) on the site. Whenever I use this component though, the route that I'm in needs to load the data and get passed to the template.
Question :
How can I load this data once and only when the component is rendered?
Also I've been reading this and still have yet to come up with a good solution. I'd like the component to provide the data source, but that seems to be frowned upon.
Would it be terrible to just do an ajax request in my component pre-render?

If you are going to need data preloaded then you can use the initializers to do that for you. You can use this data and inject to any controller , route or all of them if you want. This is a more maintainable way.
For your case you can have a particular controller have articles injected into. Then use this controller data using needs in other required controllers and thus into components.
In this way you have data available for all instance of component. Passing an store object inside the component is mostly an anti-pattern ( depends upon use cases though ) .
Component should be free from headache of data gathering and should focus on logic and presentation.
If want to know more about how to use initializers you can find it here

Related

Javascript Web Components Singleton - Where to Put the Data?

I'm coding my resume and built components for the various sections and they're singletons (there is a single section for job experience, a single one for personal information, etc.).
Each of them have data that is rendered by them (e.g the JobExperience component renders data from an object containing informaiton about my previous jobs), and that data is associated with the components 1-1.
My question is: is it a good practice to put the data inside the components, or is it better to send the data to the components externally? In my case in React, it's either passing the data via props or having it as inside the component file.
I was advised by a professional developer to put the data inside the componentsr, following the smart somponents practice.

Is it OK to use store as storage for component data?

I have read Redux doc and found out it is like the only way to share data between components, globally, and it seems like it works like on top of contexts.
The question: Can I use Redux Store for data I do not need to share across the application, like, items list got from the network, etc?
What is the best case to use Redux Store?
P.S. Edited the question about Angular as is cannot create a new one
You are mixing up Angular terminology and methodology terminology.
MVC (standing for Model, View, Controller, not Module, View, Component!) is a methodology, which divides an application into three concerns: business logic, presentation logic, and what glues them together.
Within this terminology, an Angular component is a marriage of controller and view: a template that shows how a component should look, and code that specifies how a component should behave.

Proper way of non-blocking load of unrelated models for nested route in Ember

My routes look roughly like this:
```
/
/sites
/:site_id
/settings
/user-defined-params
/:param_id
```
Now in /user-defined-params I want to display table-list of parameters assigned to that given site. The models are not related, I mean site doesn't have collection of params as a relation, so I can't simply fetch them via this relation.
Should model() hook for my router return list of these params? By default the model seems to be site loaded from parent route (:site_id). What if loading takes some time and I'd like to actually display this table (so do actual transition) but then show kind of loading indicator waiting for table to fill in with the data.
When I try to load this in model() hook, transition blocks. When I try to load it in afterModel() hook, I don't have a way to assign it and make it available for template (other than force-assigning params property to site model, which seems to be wrong).
All the examples I've found over the Internet seem to be lacking this scenario, which I feel is one of the basic ones, so any hints on that? How should I load it (ideally without blocking transition)?
The defaults in Ember's current router (as you have found) are to block UI loading completely until the promised returned in model hooks have resolved. However, there's interest in adjusting that so we can easily build non-blocking UI patterns with the built-in router.
Right now, the community consensus here is to use ember-concurrency and it's derived state (specifically the .isRunning aspect of tasks) to toggle between a loading state and a screen with the data rendered. It isn't a coincidence that ember-concurrency was built by the guy behind the first router and the current router re-think that is in-process.
One example of an approach to this is outlined here:
https://emberway.io/skeleton-screen-loading-in-ember-js-2f7ac2384d63
I personally prefer to use my route to do the initial task loading and the consume the data in the template. But in a more complex UI I also will go with container components as outlined in that article.

Reusing parameters among Angular components

When I'm sharing data among components should I call that data only once and provide it as #Input() or should I call that data again on every component's cycle?
For example, I have the following components in one page:
<game-info [id]="params?.id"></game-info>
<game-leaderboard [uid]="auth" [id]="params?.id"></game-leaderboard>
<game-progress [uid]="auth" [id]="params?.id"></game-progress>
Where I get the id from the ActivatedRoute and the uid from my authentication service. In some cases, I'm also passing a data input for multiple components in the same page.
One problem I face is that, sometimes, I'm passing data to many children components and it was harder to debug. For example:
game.component.html
<game-details [data]="data"></game-details>
<game-progress [data]="data"></game-progress>
Then, on details.component.html, I'd pass data as an input to another component - and so on. It became a really long chain:
<game-info [data]="data"></game-info>
<game-players [id]="(data | async)?.$key></game-players>
Is it a proper approach? Or would it be better to get those parameters inside of every component?
Another issue, for example, sometimes I need to get the an async parameter (e.g. uid from an Observable) during onInit but it didn't receive it yet. So, I was wondering if I should just call those parameters straight in the component instead of passing them as an input.
PS. I'm not sure if this is off-topic. If so, please feel free to remove it.
Nothing wrong with that approach. Actually, this is 1 of the recommended ways nowadays where your top-level 'smart' components would gather the data and then inject that data to your 'presentational' aka 'view' aka 'dumb' components. Note that data also flows the other way around: all Events are emitted upwards, where they are handled by the containing 'smart' component. See here for a good (better) explanation.
I must say this approach has been working very well for me: code is clean (clear responsibilities, reusability and testability of presentational components...) although I must admit I share your concern that it might become a bit tedious when you have quite a lot of nested components.
A common approach would be using it as a Injectable service.
For its benefits, as it says:
The component can create the dependency, typically using the new
operator. The component can look up the dependency, by referring to a
global variable. The component can have the dependency passed to it
where it is needed.
For angular 1, check https://docs.angularjs.org/guide/di
For angular 2, check the first answer in What's the best way to inject one service into another in angular 2 (Beta)?
It is hard to answer the question since I am not sure exactly what you are trying to achieve but it might be worth looking into services. Services will have one shared space for the components under the component it is declared under(example the app.component or even app.mudule). Then you can pass the new parameters to other components through the service. That would be the proper way of having a shared state and you can pass through many components by just injecting the service.

React router - views with dependencies

In my application, there are views with dependencies. For example, in one view a user could select an item from a list (generated on the server), and in next view the user would perform operations on the item. The item is passed to the second view in props. I'm moving to using react router, but there are some difficulties:
I can't use props for transferring data anymore. What would be a preferred way to pass data? Do I have to use redux?
Users can navigate from any view to any other view by directly using url. However, some transitions don't make sense: e.g. user navigates to item editing view from somewhere else, and therefore does not have an item selected. Is there a way to limit allowed transitions?
This is a very broad question, but I'll take a stab at it.
Can you use Redux? Sure, Redux is good for centralizing your state which can easily be shared among your components. As far as limiting the url's they have access to, I would use your reducer to look at your current state, if you're using Redux and if data is not there, meaning they should not be at this step, use a javascript redirect to where they should be instead.
Finally, you don't have to use Redux to share data between components this could be done by setting global variables your components can access, but cross component communication is where Redux shines.

Categories