Can't access component method inside 'updated' hook in vue2 - javascript

I'm new to VueJS and I'm trying to call a method inside a child component after my parent component changed the child's props.
I have the following in my child component:
methods: {
isChecked() {
if (this.cookiesTags) {
return this.cookiesTags.includes(this.tag.id);
}
return false;
}
},
updated() {
this.isChecked();
}
However, I get an error saying the isChecked() method is not a function, and I really want to avoid repeating the same code in both the methods and updated() hook.
Am I in the wrong way here? If someone could guide me to a better way of doing this it would be great also. I need to have reactivity in the child's props because the parent component is constantly changing this property via ajax, that's why I used the updated() hook here, but maybe there's a better way.
Thanks everyone!

Related

Vue3 call a components method from another component

I'm trying to have a component call a function from another component but just from
inside the setup.
I've read this from vuemastery https://www.vuemastery.com/blog/understanding-vue-3-expose/
and I see that you can accomplish this like this:
methods: {
reset () {
this.$refs.counter.reset()
},
terminate () {
this.$refs.counter.terminate()
}
}
however, I don't have access to those methods inside the setup, and I also can't use this.$refs inside the setup. Is there a way I can do the same thing inside setup, or a way to access these methods inside the setup?
Those methods are undefined in setup, and I cannot access data setup from within those functions, and I cannot use $refs in setup.
The $refs is a very easy way to call a function from another component - but I can't seem to find a relatively easy way to do this with vue3 composition api - am I missing something?
Hey I figured it out https://vuejs.org/guide/essentials/template-refs.html#accessing-the-refs
If I go
<script>
export default {
setup(props) {
const counter = ref(null);
//now I have access to counter.value.reset after it's mounted
counter.value.reset(); //does not work! it's null here
onMounted(() => {
counter.value.reset(); //here it works
})
//make sure to return counter in return
looks like there is an easy way to do this in setup just has a caveat
you cant just call it right away because setup happens before mounted https://vuejs.org/guide/essentials/lifecycle.html
I am calling it on a trigger - so if someone selects something from a dropdown I am watching the v-model and am able to call it there no problem.
Thanks for all the input.
Putting this answer here in case anyone else needs to accomplish the same thing

How to use ref on <component> in vuejs?

I am having two independent VUE components and I want to communicate between them.
In the first component, I am using <component> and added ref to it.
<component ref="dynamicComponent"></component>
and in that above dynamic component, there is a method(suppose dynamicMethod) and I want to call that method from second component.
So for that, I am using below code:
this.$root.$refs.dynamicComponent.dynamicMethod();
But I am getting this.$root.$refs a blank object. How can I call that method.
Any help would be appreciated.
Make sure you're trying to access $refs only after the component is mounted.
You should be able to access the $refs in the mounted hook.
mounted: function() {
console.log(this.$refs);
},

Force Angular child component to render completely

I have the following Stackblitz.
When I am updating the child data source it's not rendering completely, the below method is not being called,
updatedSelectedText() {
this.SelectedData = "";
console.log(this.data);
this.data.forEach(el => {
if (el.Selected) this.SelectedData += el.Text;
});
}
I can make it call on
ngDoCheck() {
// this.updatedSelectedText();
}
But in real project, I have much complex logic written, that I do not want to call on ngDoCheck method.
Is there any way to force the child component to render completely
I tried ChangeDetectionStrategy but this is not working.
In Child2Component the updatedSelectedText method is called in ngOnInit which is called only once - when component is initialized. There is two ways to solve it:
by using a setter/getter for #Input()
by using a NgOnChanges lifecycle hook
NOTE: Both setter and ngOnChanges are called before ngOnInit so you can avoid this hook
In AppComponent the update method should update the jsondata object instead change single property
Take a look on Stackblitz
Why not pass the "child2" to onEmitEvent and call to the function updatedSelectedText()?
That's, you change your app.component.html
<!--see that use a template reference variable "#child2", and pass as
argument to update function -->
<app-child1 (onEmit)="update($event,child2)" [data]="jsondata"></app-child1>
<app-child2 #child2 [data]="jsondata.AdDimensionsMaster"></app-child2>
In update function of app.component.ts just call the function
//get the "child2" as "any"
update(event: any,child2:any) {
this.jsondata.AdDimensionsMaster[event].Selected = true;
this.jsondata.isactive = true;
child2.updatedSelectedText() //<--call the function
}

React - Call setState in parent when child is called

I am building a blog in react where I get the data from a JSON-API and render it dynamically. I call setState in my app.js to get the data from JSON via axios and route with match.params to the post pages(childs). This works fine, BUT if I call the child (URL: ../blog/post1) in a seperate window it doesnt get rendered. It works if I hardcode the state.
So, I see the issue, what would be the best way to fix it?
Parent:
class App extends Component {
constructor(props) {
super();
this.state = {
posts: []
}
getPosts() {
axios.get('APIURL')
.then(res => {
let data = res.data.posts;
this.setState({
posts: data
})
})
}
componentDidMount = () => this.getPosts()
Child:
UPDATE - Found the error:
The component threw an error, because the props were empty. This was because the axios getData took some time.
Solution: I added a ternary operator to check if axios is done and displayed a css-spinner while loading. So no error in component.
Dynamic Routing works like a charme.
You can do this with binding. You would need to write a function like
setPosts(posts) {
this.setState({posts});
}
in the parent, and then in the parent, bind it in the constructor, like so.
this.setPosts = this.setPosts.bind(this);
When you do this, you're attaching setPosts to the scope of the parent, so that all mentions of this in the function refer to the parent's this instead of the child's this. Then all you need to do is pass the function down to the child in the render
<Child setPosts={this.setPosts} />
and access that method in the child with
this.props.setPosts( /*post array goes here */ );
This can apply to your getPosts method as well, binding it to the parent class and passing it down to the Child.
When you hit the /blog/post1 url, it renders only that page. The App component is not loaded. If you navigate from the App page, all the loading has been done and you have the post data in the state of the child component.
Please refer to this SO question. This should answer your question.

React Native - Modify a prop within the same component

I have simple questions:
Is it possible to modify a prop (not state) within a React Native component (not from parent component)?
Following [1], if I want to modify a prop within the same component, how can I achieve that (or workarounds if answer in [1] is No)?
If I have the following:
//Parent
render(){
return <View><ChildComponent propA={this.state.propA} /></View>
}
triggerChangeInParent(val) {
this.setState({
propA: val
});
}
//Child (ChildComponent)
render() {
return <View><Text>{this.props.propA}</Text></View>
}
triggerChangeInChild(val) {
//To set props.propA here
}
Both parent and child components are allowed to modify "propA". Whoever triggers the latest will have its value taken precedence for modifying "propA" (eg if "triggerChangeInChild" is triggered after "triggerChangeInParent", then "val" from "triggerChangeInChild" will be used for "propA".
My question is, how do we achieve that (what possible solutions/alternatives to solve this problem)? What is the best practice/pattern?
Thanks!
State is mutable and props is immutable, so you can't modify the props within component. Please do it outside the current component. If you're using redux, you can do it in a reducer.
You should modify the propA on parent only, please write a method in parent, then pass it to child via prop. So you can call the method from child, mean that you make the change inside child.
Parent
contractor(props){
super(props)
this.modifyPropsOnParent = this.modifyPropsOnParent.bind(this)
}
modifyPropsOnParent(){
// do your change here
}
render() {
return <Child modifyPropsOnParent={this.modifyPropsOnParent} otherProp={yourProps} />
}
Child can call the parent method by this.props. modifyPropsOnParent()

Categories

Resources