React-Native Passing Parent Function as prop to Child Component - react-native

I'm getting very frustrated because there doesn't seem to be a post that solves my issue. In a Parent Component have an array that stores a list of objects, and a method that appends to this list. [for reference here's a snipbit]
In the render method of my parent component, I pass this method as a prop to my child component.
[line 79]
https://i.stack.imgur.com/fStiF.png
And my child component tries to call said method, in it's render()
in render's return, child component
https://i.stack.imgur.com/crN9T.png
However for some reason I get an Error this.props.addPart is not a function
Complete Code:
WaitlistTable.js 1-34
WaitlistTable.js render 34-56
CustomerAdd.js 1-35
CustomerAdd.js call to addPart in render

Make your addPart function an arrow function
like this
addPart = (..,..,..) => {...}

Related

Call grandchild function from a child - vue.js

I have 4 components in vue, I want to call a grandchild function('refreshArtifact') from a child component, any idea how can I do it?
So here is my component hierarchy:
Parent : TeamManagment.vue
Children :TeamPlatform.vue & ManagementArtifcts.vue
GrandChild : TeamAction.vue (TeamPlatform.vue child)
i want to call the 'refreshArtifact' function in TeamAction.vue from the ManagmentArtifact.vue component.
In my opinion, you can't right now directly call a child function of a brother. So, with your code, you can't directly call a function of a component A, from a component B which is the brother of the A one.
But, you can do that with the grandparent component.
So, when the ManagmentArtifact.vue component need to call refreshArtifact function, you can emit an event. The TeamManagment.vue listen that event, and then pass use ref of TeamPlatform.vue component to call the function.
ManagmentArtifact.vue: this.$emit('callRefresh')
TeamManagment.vue: <ManagmentArtifact #callRefresh='refreshArtifact' />
<TeamPlatform ref='team' />
methods: { refreshArtifact(){ this.$ref.team.refreshArtifact() } }
You can read the doc here.

At what point in the component lifecycle does a prop get injected into a component?

I have a Parent component that is passing an array, let's call it 'bucket' that contains a bunch of stuff, to a Child component.
In my parent component, I have the following:
<child-component
:bucket=bucket
></childcomponent>
In my child component, I have a props section, that accepts a prop called bucket, and has it defined as an array, like so:
props: {
bucket: Array
}
Now in the mounted section of my child component, I want to take this bucket of stuff, and do something with it. However, for some reason, it shows up as empty. So when I do this in my child component...
mounted() {
console.log(this.bucket.length)
}
... I get a 0. When I check Vue dev tools, I can see that there are items in the bucket array in the Child component's props section. Furthermore, if in the console, with the child component set as $vm0, when I type $vm0.bucket.length, I get the correct size.
What on Earth!? Is the prop not injected yet when mounted is called in the Child component? If so, when does this actually happen? How do I get around this? Super confused.
Thanks!
try to add directive v-if
<child-component :bucket="bucket" v-if="bucket.length"></childcomponent>
if you can get this.bucket.length on component mounted this time, maybe #Stephen Thomas is right.
As you said in the comments, you are pushing new items to the bucket array.
Instead pushing items into the array, you should create a new array with the new items, example:
this.bucket = [...this.bucket, newItem];
Vue reactivity works when the value is changed, pushing a new item into an array is doesn't change the variable's value.
When you attribute an Object or Array to a variable, it's memory address that is given to the variable, so changing it's internal attributes or pushing new items won't change it's memory address.

How to send communication to parent component from child component?

I have split up the components only for the reason the base or the parent component code is growing in size and for code organization. so split the components based on the sections of the parent component.
So the each child component are the each section of the same parent component. But my question how to access the child component objects from parent component? Because most of the examples i see are based on the click event from parent component to view the child component (like dialog) and the value is passed back to the parent html click event and captures the values using emitter and output parameter.
Whereas in my case there is no such click action to trigger the child component. So how to communicate the values from child component to parent component?
In parent component
onDocumentSelect( documentData: IDocument) {
console.log(documentData);
}
<app-document [showDocument] = 'displayDocument' (selectDocument)=onDocumentSelect($event)></app-document>
In Child component:
#Output() selectDocument: EventEmitter<e.IDocument>;
#Input() showDocument: boolean;
I am triggering emit in the function where the data for the DocumentSource is computed.
this.selectDocument.emit(this.DocumentSource.data);
here this.DocumentSource is the dataTable which has value in Child component, that needs to be accessed in parent component.
Apart from this I have similar data for another field of different type needs to be passed to parent component from child component.
I get the below error while page loads
TypeError: Cannot read property 'subscribe' of undefined
In the above code snippet, by changing the type to any solved the issue.
On child component:
#Output() public selectDocument: EventEmitter<any> = new EventEmitter<any>();
On parent component:
onDocumentSelect( documentData: any) {
console.log(documentData);
}

Pass Function as Property to Vue Component

I am trying to make my Vue Component reusable but there is a part in it which requires to run a function on button click which I have defined in the parent component.
The component's button will always run a parent function and the parameter it passes is always the same (its only other property).
Right now I am passing 2 properties to the component: 1) an object and 2) the parent function reference, which requires the object from 1) as a parameter.
The Child-Component looks like this (stripped unnecessary code):
<button v-on:click="parentMethod(placement)">Analyze</button>
Vue.component('reporting-placement', {
props: ['placement', 'method'],
template: '#reporting-placement',
methods: {
parentMethod: function(placement) {
this.method(placement);
}
}
});
The parent is making use of the child like this:
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement"></reporting-placement>
methods: {
analyzePlacement: function(placement) {
this.active_placement = placement;
},
}
As you can see, the child has only one property, placement, and the callback reference. The placement must be put in as a parameter to the reference function from the parent.
But since the parent defines the parameters, the child shouldn't concern itself with what it needs to pass to the parent function. Instead I would prefer to already pass the parameter along in the parent.
So instead of
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement"></reporting-placement>
I would prefer
<reporting-placement v-bind:placement="placement" v-bind:method="analyzePlacement(placement)"></reporting-placement>
(including appropriate changes in the child).
But passing the parameter along does not work that way.
Is it possible (maybe in other syntax) to 'bind' the variable to the function reference so that it is automatically passed along when the callback is called?
Info: I don't get an error message if I write it down as above but the whole Vue screws up when I pass the parameter along to the component.
Hope the issue is clear :-) Thanks a lot!
By reading your proposal I've found out that you are overusing the props passing.
Your concern that child component should not have any knowledge about the way that the parent component uses the data is completely acceptable.
To achieve this you can use Vue's event broadcasting system instead of passing the method as props.
So your code will become something like this:
Vue.component('reporting-placement', {
props: ['placement', 'method'],
template: '#reporting-placement',
methods: {
parentMethod: function(placement) {
this.$emit('reporting-placement-change', placement)
}
}
});
And you can use it like this:
<reporting-placement v-bind:placement="placement" #reporting-placement-change="analyzePlacement($event)"></reporting-placement>
But if you need the data which is provided by the method from parent it's better to consider using a state management system (which can be a simple EventBus or event the more complex Vuex)
And finally, if you really like/have to pass the method as a prop, You can put it in an object, and pass that object as prop.

Modifying a component's state from another component

I'm trying to set the instance variable of a child component from it's parent component inside a callback. Using the debugger I can see that the instance variable is set correctly in the callback, but on rendering the child component, the child component does not reflect the changes made.
So, is it illegal to modify a component's state from another component in seaside or am I doing something else wrong?
Example code:
MyParentComponent>> initialize
super initialize.
child := MyChildComponent new.
MyParentComponent>> renderContentOn: html
html render: child.
html anchor
callback: [
child property: 'Something'.
] ; with 'Navigate'.
MyParentComponent>> children
^ Array with: child
You miss some super initialize in the parent component I guess.
I also suggest you don't work this way.
Do a MyParentComponent>>child with
^ child ifNil: [ child := MyChildComponent new ]
Also, don't do a html render: child but html render: self child.
That way you'll be able to swap components easily.
That way you are sure that child has been properly initialized.
After a little experimenting, I found the problem. In one of the rendering methods, I was creating a new component each time the page was rendered instead of reusing the one created in the initialize method.
That other component was used for navigation, where I set which main component was to be displayed based on the menu chosen.
So apparently, modifying state is not illegal in Seaside.