i have a grandparent component that a service for Observable response of HTTP get request.
i need those results to be passed to 2 child components , load to a table (if there's results) and only then the child component should be render.
how can i achive that? i guess a service will be the right way to go but i need the results to be available before the child components view rendering, so maybe there's a component lifecycle hook involved it the solution as well.
i tried transfering the data using dependency injection on the grandparent but the child was already rendered with no data.
i also tried a bit with services but was unable to achive the result i want.
i'm using Angular 5.
Probably you can conditionally (with *ngIf) show/hide your child components. For condition statement you can check whether or not your Result object is initialized.
i used EventEmitter on the service and subscribe to it by the child component.
that solved it and handle the dynamic data loading for me.
Related
While I'm learning React, it's always said that you should keep your state in the parent component and pass them as props to its children.
But in the real world, whenever I start building a react app, I end up passing data from a child component to its parent.
For example, if I have to implement a form somewhere in my react app, I create an extra component for it (for example, FormComponent) and import it in my App component.
But now, I have to pass the form data form the FormComponent to the App component. In other words, from the child component (FormComponent) to the parent (App component).
And this was just an example. Usually, I always end up in situations where I have to pass data from child to parent rather than the other way around.
Do I misunderstand the concept of passing props completely?
If we stay with the above example, is my approach, right?
You can't pass data from child to parent as in React, The Data Flows Down.
So usually you pass callbacks from parent to its children, but the state remains in the parent.
This is commonly called a “top-down” or “unidirectional” data flow. Any state is always owned by some specific component, and any data or UI derived from that state can only affect components “below” them in the tree.
If you in a situation where the code becomes unreadable, unmaintainable, you should consider Lifting the State Up.
Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor.
Aside from it, a common anti-pattern is Prop Drilling, Context API, and many state libraries like Redux, MobX, and Recoil trying to solve such problems with some extra features.
1- In your case you can pass a function ( Example: handleSubmit() ) through props from parent to child.
And so when this function is called the child's data would be hundled from the parent.
you can use this doc page to inspire your code.
2- Otherwise you can use react redux, and then you can hundle all data at any component in your project using one global state called redux store.
want to learn more about react redux click here.
3- Have a nice day ^_^ .
I have 3 components.
1 parent and 2 child component with router outlet so child component is active whenever its route is called (sharing data using service).
I have complex view for both of this child components.
when i switch between this two routes it takes too much time to render view. ( i have used some bootstrap UI, ngbootstrap, and some more libraries)
my data is not changing between this 2 child components only view part changes which takes time.
so i was wondering is there any way to cache this component once they are called ? to improve performance ?
thanks in advance.
That is a good question, I've never used it, but you can achieve that with RouteReuseStrategy. You didn't provide your specific example, but generally you need to use methods:
shouldAttach - returns true/false to determine whether retrieve method will be called to fetch the component instead of creating it from scratch.
retrieve - returns RouteHandle or null if it's called - it can return saved (cached) component as a DetachedRouteHandle.
shouldDetach - returns true/false to determine whether store method will be called.
store - returns nothing but accepts detachedTree that you can save (cache) to store your component state and further return it from retrieve method.
It sounds complex, but it's easier to do that, than replacing router-outlet to some custom thing. Here is the guy describes that really well and provides an example. Hope that helps.
I have three components. recipe, recipe-item and recipe-details. On clicking on a recipe from recipe-item component, recipe details of that particular recipe is displayed (i.e recipe-details component is getting activated).
I have one common service - recipe-service. Which I am thinking to use it for communicating between all the components.
Approach 1: When I click on a recipe from recipe-item, I will call a function which will point to another function in recipe service which in turn will mark a variable currentRecipe as the clicked recipe passed from recipe-item. This currentRecipe value I will access in the recipe/recipe-details components through ngOnInit to display the details. Will this approach work? will the view change as the variable changes in the service? I am doubtful of this approach as the ngOnInit only checks while initiating the component.
Approach 2: When I click on a recipe from recipe-item, I will call a function which will trigger an event emitter that was declared in the service, but emits currentRecipe directly from the recipe-item component. And, I will subscribe to this event from the ngOnInit of recipe and recipe-detail components to display the details.
I am a beginner and I am confused between the two approaches. I tried the first approach which did not work. The second approach works. I am not sure why the first approach did not work. In which scenario I should be using the first approach and in which scenario I should be using the second approach?
Thank you for the help!
Both approaches will work, i would suggest you go with the 2nd Approach as both of your component are dependent and have a relationship.
You could use the #input() event emitter to transfer the details to the child component.
I use componentDidMount() method in my parent React component to fetch some data from API, which are then saved in redux-state.
In my render method, I have another component which should use data from the global redux-state.
I can send data to my child component via props or I can load them using mapStateToProps().
If I try to console.log or assign data to var from props in my child component constructor or in componentDidMount() method, I'm not getting my data as expected (I'm getting initial state).
Console.log in my render method will show me initial state at first rendering, on the second it will show correct data.
I need point where I'm sure that I have correct data.
...where var a = this.props.somethingFromState; will be assigned correctly.
Is render method best place and what is best practice for doing this in general. Thanks.
There are a couple of questions here.
With respect to where to load data, componentDidMount is indeed the correct place to call ajax methods and load data as suggested by the facebook docs.
In terms of whether or not to then pass that data down to child components via props, I like to follow Dan Abramov's (the author of redux) guid on presentational vs container components. In short, try to have a container component that loads your data and does all the logic, and then pass whatever is necessary down to presentational components via props, making them pure functions if possible.
In terms of when you will have the correct data, check the React lifecycle docs above. You will see that the constructor fires, then componentWillMount, then render, then componentDidMount. So if your ajax call gets the data in componentDidMount, you will have called render first, resulting in no data being loaded on the already mounted component. Most people solve this by putting a spinner until the data has finished loading from ajax. A simple if statement should accomplish this
Using Ember I have a parent route with two nested child routes each child with a dynamic segment. The parent route does a calculation on its model to determine the “default” value of the dynamic segment for its child. Then the first child does the same for its own child route.
Everything is working well. However, what I’m seeing is that the adapters for the parent route and first (outer) child are being called twice. This causes a performance hit.
At each point where I do the calculation for the dynamic segment, I then do a “transitionTo” with the calculated value to load the child route. This is happening in the afterModel hook. I’m guessing that’s where the problem lives.
I’m able to prevent the second call to the adapter by checking the store to see if it’s already cached by that id. Is this what I should do or is this a hack required only because I’m misusing transitionTo in afterModel?