ngOnInit or ngOnChanges not called while manually calling changeDetect() on a component - angular5

I have 3 component out of which p1 is parent and c1 and c2 is child ,
in c2 i am triggering the change detection by calling
this.changeDetecionRef.detectChanges()
But this will not triggered . no ngOnChanges or ngOnInit function get called of Parent and child component.
Does I have to update any property i.e binding data from parent to child or child to parent .

ngOnChanges is called only when the data-bound property was changed.
ngOnInit() is called, After all of the injected dependencies resolved. (It should call after ngOnChanges())
binding data from parent to child component,
parent.component.ts
#Component({
selector:'parent-component',
template:`
<h1>Welcome</h1>
<button (click)="changeCount()">Change</button>
<child-component [count]=Counter></child-component>`,
})
export class ParentComponent{
Counter=2;
changeCount(){
this.Counter++;
}
}
child.component.ts
#Component({
selector:'child-component',
template:`<h2>Total Count {{count}}</h2>`
})
export class ChildComponent{
#Input() count:number;
}
detectchanges() method should be called after updating the property,
for example,
export class ParentComponent{
Counter=2;
changeCount(){
this.Counter++;
this.changeDetecionRef.detectChanges();
}
}

Related

call parent method in child component using vue.js

hello everyone i jusy wanna know how to call a perent function from a child component
i've tried to use the $parent to call the perent method but i have this error typeError: _this.$parent.forceRender is not a function
here's the parent method that i'm trying to call
methods: {
forceRender() {
this.componentKey += 1
}
},
and here's the child component as you can see i'm trying to call the parent method using the $parent
this.$parent.forceRender()
You can send the functions as a props to the child component jus like follows
<child-component :forceRender="forceRender" />
inside the child component you can received it like this
props: ['forceRender']
and then call it as
this.forceRender()
You should emit an event from child to parent component in order to run a parent method :
in child component:
this.$emit('force-render')
in parent component add #force-render to component tag with forceRender as handler :
<child-component #force-render="forceRender" />

Property or method "title" is not defined on the instance but referenced during render. Make sure that this property is reactive

I have parent and child components and I am trying to pass props between them. the parent is called links and the child is link-encoded. I have the child like this in the html template
<links-encoded title="hellooo"></links-encoded>
and in vue file for the parent i have
data() {
return {
title:"helloooo"
}
on the child vue i have
export default class LinksEncodedComponent extends Vue {
props: ['title']
}
and in the child html
<p>{{title}}</p>
This is the proper way to bind title data property of the parent to the title prop of a child:
<links-encoded :title="title"></links-encoded>
fixed i had to put props: ['title'] inside #Component()

Vue lifecycle hook - conditionally prevent creation

Is there a way to prevent component creation during the lifecycle hook? For example:
beforeCreated() {
//checking value from vuex store
if (this.$store.state.attendeesCount >= this.$store.state.maxAttendees) {
//prevent further propagation, don't create an instance of component
}
}
The case is, I have a parent component with multiple child components which contain form for creating attendees (1 component = 1 attendee). I would like to prevent the creation of the child component if the seminar is already fully booked.
Update:
Parent component is base component for dozen of multirow form components and I didn't want to perform checks there to keep it as abstract as possible.
Instead of actually preventing creation of child component during the lifecycle hook, I have emitted custom event once the condition is met. Parent component listens to this custom event, and deletes child component instance.
Child:
beforeCreate() {
if (this.$store.state.attendeesCount >=
this.$store.state.maxAttendees) {
this.$emit('preventCreation', {message: 'No more places'})
}
}
Parent:
<template>
<component v-for="(item, index) in components"
#preventCreation="preventCreation(index, $event)"
...
>
</component>
...
</template>
...
methods(){
preventCreation(index, payload){
this.components.splice(index, 1)
alert(payload.msg)
}
}

vuejs: call function from parent from child dataAttr

I have a wrapper component (waypoint) which collects child elements. On the child elements I want to set functions which should be executed from the wrapper component, how can I do that?
//page
//template
<v-waypoint>
<div
:data-wp-cb="animateIn"
// :data-wp-cb="animateIn.bind(this)"
class="js-wp"
//methods
animateIn() {
// do something
}
//waypoint component
update(el) {
const cb = el.dataset.wpCb
cb() // cb is not a function
}
How can I make this work?
You should solve it emitting the event from child to the parent.
Waypoint component:
update(param) {
this.$emit('update-from-child', param);
}
Page component:
<v-waypoint #update-from-child="localMethod">
<div
:data-wp-cb="animateIn"
// :data-wp-cb="animateIn.bind(this)"
class="js-wp"
This is how vue deals with child -> parent comunication. For more info, check the docs.

How can I get a child component's watcher's updated value from parent component in Vue 2?

I have two components that are in a parent-child relationship. In the child select component I've defined a watcher for the currently selected value and I want the parent to get the updated value whenever it changes. I tried to use events but the parent can only listen to its own vm.
In the child component
watch: {
selected (value) {
this.$emit('selectedYearChange', value)
}
}
In the parent
mounted () {
this.$on('selectedYearChange', function (value) {
this.selectedYear = value
})
}
This obviously doesn't work because of the reason I mentioned above.
I wasn't able to find relevant examples in the documentation.
You can setup an event listener on the child component element itself where its used in the parent and pass it a method to be executed
//parent component
<div id="app>
<child-comp #selected-year-change='changeYear'></child-comp>
</div>
In your parent component use the method changeYear to change the value of `selectedYear'
methods:{
//you get the event as the parameter
changeYear(value){
this.selectedYear = value
}
}
See the fiddle
And avoid using camelCase for event names use kebab-case instead as HTML attributes are case-insensitive and may cause problems
html:
<Parent>
<Child #selected-year-change=HandleChange(data)></Child>
</Parent>
Javascript/Child Component:
watch: {
selected (value) {
this.$emit('selectedYearChange', value)
}
}
Javascript/Parent Component:
HandleChange: function(data){}
good luck. maybe work!