queryParam not working right with angular routing - javascript

I currently have a router with a path set like so:
{path: "application/:id", component: ApplicationComponent}
I generate a menu of links by using an ngFor loop. it uses the index to generate a dynamic routerLink of:
routerLink="application/{{index}}"
Once clicked, it travels to the correct URL and uses my ApplicationComponent's ngOnInit method to grab the index in the url and pull a specific object out of an array in a separate class.
HOWEVER it only works for the first link you click on. If I click on link 1, it loads the page correctly with object 1's data. But when I click link 2, it travels to application/2 in the url but keeps object 1s info up. If i refresh the page and click link 2, object 2's info is shown, so I know it is pulling from the array correctly.
I suspect that once any links are clicked the ApplicationComponent uses the ngOnInit method to make the component, and then if another is clicked, this method is not called so the variables are not getting updated.
How can I solve this problem? I need the Application Component to know that ive traveled to a new sublink so it can call ngOnInit again

ngOnInit is only called once, when the component is loaded. So if you navigate to application/1, ngOnInit is called. If you then navigate to application/2, ngOnInit is not called again because the component is already loaded. You need to use something like paramMap from ActivatedRoute to detect when a parameter changes.
ngOnInit(){
this.activatedRoute.paramMap.subscribe(paramMap => {
let id = paramMap.get('id'); // id gets updated whenever parameters change
// add or call any code that needs to re-run when a parameter changes here
});
}

Related

How can i get data from an action before other actions ? VUEX/NUXT

I have two actions in my store:
GetHitProducts
GetNewProducts
They are called in two different components:
sliders Component with GetHitProducts going first by HTML
So anyway the action called second or first by order sometimes, I need to set my first component like with an important priority. Because data after commit by GetHitProducts is using in the second component. Else I do have an error.
In slider's component, I do have a component Product.
In that component I make some logic that needs to store data in hitProducts, but if second slider's component renders first, it would not have stored the information and I get an error.
Can I call the action first when the page is loaded or something like that?
Maybe problem with the render priority, so is it possible to set the priority?
If yes, how can I do that ?
Main task is to get data by action GetHitProducts before render other components what will call other actions.
Store File HitProducts
Store File NewProducts
Component File HitProductsSlider
Component File NewProductSlider
THE PROBLEM - DEVTOOLS CALLED ACTIONS
Component PRODUCT and logic in the mounted
you can get data for the first component and watch the variable you are storing it's data, whenever watch triggers get the data for second component.

Why ReplaySubject is getting called on ngOnInit?

I am trying to interact between 2 components i.e. the header component and the router-outlet component which contains a reactive form. Some days ago after great research, I got an answer which told me to use shared service and there takes a ReplaySubject variable. This will act as an Observable which will be called in ngOnInit of the component in router-outlet. So the problem arises here. Everything is working fine but just now while testing noticed a small bug. After clicking the button in header the event is firing in the main component but it is staying active until I hard reload the page.
Below is my code:
shared.service.ts
public updateSrc = new ReplaySubject<any>(1);
public updateClick = this.updateSrc.asObservable();
header.component.ts (A button is clicked here)
update() {
return this.dataService.updateSrc.next(true);
}
main.component.ts (Here the main operation is happening on click of header button)
updateClicked = new Subject<any>();
ngOnInit() {
this.dataService.updateClick.pipe(takeUntil(this.updateClicked)).subscribe({
next: value => console.log(value); // At first click of button this happening perfectly but if coming from different route & had clicked the header button previously this thing is getting triggered
});
}
ngOnDestroy() {
this.updateClicked.next(); // Closing subscription here
}
Can anyone suggest to me how to reset this?
The ReplaySubject (and the BehaviorSubject) stores previously emitted values and emit those whenever a new subscriber is added.
If you don't want new subscribers to receive previously emitted value(s), you can always use Subject which doesn't store emitted values.
You may want to read more about the available variations in the docs.

initialize state react, to solve undefined when the page first rendered

I want to map a state, but that state (the name of the state is "task", it is the child of parent state called "timesheet", the "timesheet" state is already defined using componentWillMount) is still undefined UNTIL an action creator has been triggered (click a button) inside my page. But, i already define timesheet.task.map inside jsx, and thus the page cannot load and it shows an error "cannot read property map of undefined".
code
So as you can see here, i want to map a list of 'select' options from a state which is called when an event is triggered (it is still undefined when the page renders), but the page will not load because the timesheet.task is still undefined when the page load the first time
Do you have any idea how to fix this? I was thinking to initialize the state, but i don't know how to do it.Thank you very much!
Very common situation. At the top of your render() - just add a conditional to check if that value is valid or not.. something like:
if (!this.state.timesheet.task) {
return <p> waiting for my value </p> // add any generic component to here that would await your value
}
Depending on your page layout, you might want to just create a small component to inject as a conditional as you await your value to be populated.

React page does not rerender on url query change

I'm trying to create a react page having different content based on the query in the url. ex: things?type=0 and things?type=1 resulting in different filtered content.
The problem is, React isn't triggering a rerender of my page when switching to these pages. I need to manually refresh the page to get the desired result.
I tried to use the build in lifecycle features but non of them triggers the page to refresh. It tried to do my fetch in the componentWillReceiveProps method with then I have to click twice on the link to get my filtered content (which is better than no page refresh but not user friendly).
I use this reference.
You will probably want to use https://github.com/reactjs/react-router or some similar library for routes.
If you want to go on your own you have to listen to browser history changes. You could do it like this for example:
componentDidMount: function () {
var component = this;
window.onpopstate = function() {
console.log(window.history.state);
component.setState({
query: window.location.search
});
};
};
I am not sure if this is the good way to go, but it should work at least.

Passing Huge data between Vue js routes

I have an application which searches for flights using Vue.js and Vue Router.
I have two components, first one is search, which is on the base route '/'. When user clicks on search, it will send a request to server and gets a huge list of flights.
Then I need to call the result component on '/results' route and show the results using v-for.
I have two questions, first, how can I manually redirect to '/results' after I get the results.
Second and more important, what is the proper way of passing the results data to results component to use?
Inside your results components, you can put transition hooks in the route object. Read here: http://vuejs.github.io/vue-router/en/pipeline/hooks.html
The activate hook runs when a component is activated, and the component wont appear until the activate hook has run. Here's the example on that page, which would be similar to yours:
route:{
activate: function (transition) {
return messageService
.fetch(transition.to.params.messageId)
.then((message) => {
// set the data once it arrives.
// the component will not display until this
// is done.
this.message = message
})
}
}
So basically when they click search you send them to /results and this hook will handle loading the data in between.
Here's an advanced example of a mail app using vue-router that shows off a lot of the transition hooks in action: https://github.com/vuejs/vue-router/tree/dev/example/advanced

Categories