Vue 2 load ajax data before component render - javascript

I have a few nested Vue Components and the child loads the data using an AJAX call. Is it possible to have the parent wait to finish mounting until the child has made the ajax call and finished rendering? I have seen some solutions that use async created() or beforeRouteEnter: function (to, from, next) but I cannot seem to get it to work on the Fiddle.
I have a jsfiddle posted here: https://jsfiddle.net/likwidmonster/20potzwc/16/
In the jsfiddle, I have nextTick functions that print to the log when each is loaded. I would like it to have the following output:
grandchild next tick
child next tick
grandchild next tick
child next tick
grandchild next tick
child next tick
parent next tick

You cannot stop the parent from loading so to speak, but you can make it seem like it is by applying v-cloak, v-if, or v-show to the top level HTML element in the template. You can have a property on the parent, such as:
loaded: false
You can then use sync to synchronize this value with the parent and child, by attaching it to the child like this:
<child :loaded.sync="loaded"></child>
Then, within the child, you can use $emit when your Promise resolves:
this.$emit('update:loaded', true)
Which will tell the parent to change loaded from false to true.
Finally, you can make sure the parent isn't rendering until that variable is try by attaching a v-show directive which and passing it the loaded variable:
<div v-show="loaded">
So on initial page load this is false. When the data is finished loading and the child $emit's, then it will be true, and the parent will become visible.

Related

How do you update state in parent component from a child component when an event takes place in the parent component

I have to update state of the parent class component from child functional component only when a click event takes place in the parent component. Right now I've access of the data from child to parent component but when I update the state I get error, maximum depth reached. So I thought it'd be better to update the parent's state from child only when the certain event takes place in the parent component but I'm unable to find any approach. Could you please show some light?
From your description, the best thing to do is to lift state up from the child to the parent so that the information you currently only have in the child is available in the parent (which can provide it to the child as a prop). Then, the child isn't involved in this at all, the event in the parent updates the parent's state, which is standard.
But if you absolutely can't do that:
It's taking you off the beaten path, but you could:
Have the parent pass the child two things:
a means of subscribing to an event from the parent
a function to call to update the parent's state
Have the child subscribe to the event
Have the parent raise the event the child subscribes to when the click occurs
Have the child respond to that event by calling the function from (1)(2) above
While that would work, it's a bit convoluted. So again, if you can avoid it, move the state needed for the update from the child to the parent and keep the entire update in the parent.
Finally I figured out a way to achieve it.
Step 1: Set a boolean for your event taking place in your parent state using useState hook.
// Inside Parent component
const [eventInParent, setEventInParent] = React.useState(false);
Step 2: pass the eventInParent as prop to your child component
// Inside Child component
Step 3: Receive the event status (eventInParent) in your child component in your props and use it as a dependency in useEffect hook
React.useEffect(() => {
if(eventInParent) {
}
}, [eventInParent]);
As you can see every time event will hit in parent component the eventInParent value will change which will trigger the useEffect hook in the child component.

React: moving to a particular child component of my react app

I have a callback function which receives an argument from child component(here CardTiles) and it is processed and passed as props to another child component. The output is displayed correctly but I have to move my page to that particular section(the second child component-OutputWindow). How can i trigger an anchor tag from my 1st child component? or would refs work here?
Child component 1:
<CardTiles parentCallback={handleCallback}/>
Child component 2:
<OutputWindow name={place}/>
or would refs work here
Yes. Have a ref in the parent, put it on the child (ref={theRef}), have the child forward that ref to the outermost (probably) HTML element it renders, and then in the callback function have the code use theRef.current?.scrollIntoView()¹ to scroll that element into view.
More
Refs
Forwarding refs
scrollIntoView
¹ That's using optional chaining, which is fairly new. If your project isn't set up for it, you can use if (theRef.current) { theRef.current.scrollIntoView(); } instead.

Vue.js eventBus doesn't emit property after page refresh

I want to pass property from one component to other, they are siblings, after a page refresh. I want to do this on the page load.
I am using eventBus to do it:
EventBus.$emit('generatedSum', this.sum);
Receiving it in the sibling component with:
EventBus.$on('generatedSum', (sum) => {
this.correct = sum;
});
and I am puting both in the lifecycle hook:
created(){}
The problem is that after code is compiled after a saved change, I get the property emited to the sibling component, but when I manualy refresh the page the property is not visible in the sibling component.
I think when the page refreshes the Vue components mount one after another. Since both are siblings, when the first component trigger the event the second component may not be available to listen to the triggered event. Because the second component is mounted after the first component.
As a work around try
mounted() rather than using created() life cycle event.
More on life cycle events can be found here.
https://v2.vuejs.org/v2/guide/instance.html#Lifecycle-Diagram

How to detect when DOM is ready after *ngIf condition is set to true

I have an Angular 2 (Ionic 2) application where I hide some elements using an *ngIf if the network is offline, and show another button, "retry".
When I click the retry button, if the network is back I then want to reshow the elements hidden by the *ngIf. Also I then need to reference some of them via #ViewChild (e.g. an Ionic 2 slider to get it's current index). My problem is that these elements are not all defined when I try to get a reference to them in the same function call that sets my property bound to the *ngIf back to true.
I have tried calling from within a setTimeout but this does not seem to be very safe - some DOM elements are back but not all.
Is there a way to know then the DOM is ready with all the elements that were hidden by the *ngIf, or do I need to find some other way of doing this (not using the *ngIf, so elements are not actually removed).
Thanks in advance for any suggestions!
You should be able to do what you want by looking at the onStable event emitted via the NgZone:
In the component template:
<button (click)="showFoo = !showFoo">toggle</button>
<div *ngIf="showFoo" #foo >foo</div>
In your component class
#ViewChild('foo') foo: ElementRef;
showFoo = false;
constructor(private zone: NgZone) {
zone.onStable.subscribe(() => {
console.log(this.foo);
// this will log either undefined or an ElementRef as you toggle
});
}
Here's a plunk showing it working: https://plnkr.co/edit/jKSaEI0XUcJQehZnJTxB
I think you are looking to understand this,
I think the ngAfterViewInit() would help you with this,
ngAfterViewInit() Respond after Angular initializes the component's
views and child views.
Called once after the first ngAfterContentChecked().
A component-only hook.

How can my child component update my parent component in React JS?

My parent component is a list of tabs. Clicking on tab leads me to Child #1 or Child #2. I can also route to Child #1 or Child #2 by URL. In this case, I check the path to know which tab to select programatically.
My problem comes when I redirect from one child to another. My parent is oblivious to the fact that a change has occurred - none of the initializing functions in that component get called, since it is already rendered. Therefore the tab that was originally selected (Child #1) - remains selected even though I am now viewing Child #2.
The tab that is selected is being stored in the parent's state - is there any way for me to update the parent's state from the child component?
Pass a function down to the child(ren) from the parent that modifies the state accordingly. A very simple version could be something like:
class Parent {
setActive(activeId) {
this.setState({active: activeId});
}
render() {
return (
<Child setActive={this.setActive}/>
);
}
}

Categories