Access data inside dynamic components from parent component in VueJS + Vuex - javascript

I created this demo to explain better my goal: https://codepen.io/Albvadi/pen/OJMgByR
Each button create a new alert creating a object inside the vuex store in the components array. With the component property I know the type of the component to render.
Each alert generate a random string in a data property inside the component.
How do I need to configure the connection with Vuex to obtain the data from the child alert component inside the global components array?
Thanks!

Finally, I solved with a computed property that gives me the parent item. I don't know if it is the best way or if there is a simpler one, but I think it is the correct one.
computed: Vuex.mapState({
getParentItem(state) {
return state.components[state.components.indexOf(this.index)];
}
}),
Demo solved: https://codepen.io/Albvadi/pen/wvMrpLv

Related

Unable to retrieve TinyMCE's content from a parent component

I have asked the question on their Github but no answer so far so I'm trying my luck here.
I'm creating a form that contains TinyMCE as component ; my goal is to be able to use and reuse this component through the whole website as the main Wysiwyg. I import it, give it a v-model and I'm good to go.
So, it "works", as in, I can set a value via the v-model and TinyMCE will display it nicely. However, it looks like I'm on a write only mode, because I can't extract the current data from it.
I originally created an example for the Github issue, you can see it here so that you have a good idea of what I'm facing. There's a textarea under the TinyMCE component that has the same v-model, just try to play with it and see the behavior.
While everything works if I declare a v-model inside the TinyMCE component, what do I need to do
get my value to the parent component?
Thanks in advance
You need to use v-model on the editor itself too or else it only receives the parent value but can't update it. However, you can't use the prop value for that because props can't be mutated.
Using a computed setter with v-model is a good solution here:
<editor
api-key="qagffr3pkuv17a8on1afax661irst1hbr4e6tbv888sz91jc"
v-model="model"
></editor>
Leave the value prop as is and add the computed:
computed: {
model: {
get() {
return this.value;
},
set(val) {
this.$emit('input', val);
}
}
}
The computed setter returns the prop when getting, but emits rather than setting it.

Is it possible to return a value of an inner object of the wrapper object in Vuex getter before mounting?

I am currently working with Vuex and VueJS, and I got stuck in a problem with the Computed property.
In a nutshell, I have an object which has an inner object in Vuex state, try to access the key of the inner object in Vuex getter to return the value, and render it in a component. However, I get an error like "cannot read property id of undefined".
I think there are two important points to the problem.
The first one is that I can render the value if I put the value into a variable of the data option in mounted() with using the settimeout() method.
The second point is that I can access a key of an object, return the value in Vuex getter, and render it in a component correctly.
I would like to know if it is possible to return the value of an object in the wrapper object in Vuex getter to render it before mounting a component.
It would be great if you could answer my question. Thank you in advance.
Sample code of Vuex getter
According to the error, you don't have the _user property when you are trying to access it via vuex getter. I think you are fetching it from and API, as i understood.
On your state, set profile as empty/nested object with all fetchable properties to get rid of errors.
Like;
const state: {
profile: {
_user: { _id: null }
}
}

Angular (9) sharing common state between components

In current (2020) Angular, I have two components that are intended to share the state of activeProject through a service. I have the following defined on an ApplicationProjectService:
private activeProjectSource = new BehaviorSubject(undefined);
activeProject$ = this.activeProjectSource.asObservable();
set activeProject(v: any) {
this.activeProjectSource.next(v);
}
get activeProject() {
return this.activeProjectSource.value;
}
I'm using BehaviorSubject in the service since I want components to get the current value upon subscribing without any change. The getter/setter is there because I was doing some other binding directly to a service property, which I've since learned is not recommended.
The two sibling components that eventually trace back to a common parent, but I'm not using #Input() or #Output() or any parameter passing in the DOM:
this.appProjectService.activeProject$.subscribe(activeProject => {
this.activeProject = activeProject;
});
Each component is binding to the this.activeProject property in their respective component using [(ngModel)]:
<input type="checkbox" [(ngModel)]="activeProject.someProperty">
Question
If each component obtained what I thought was a copy of activeProject through this.appProjectService.activeProject$.subscribe(), how is it working that a change to the local property in one component is reflected in the other? In the end this is the behavior I want, but I can't understand why it works. Is there some passing by reference that I'm not understanding in rxjs observables?
sIf you have 2 components, the both local variables activeProject use the same reference of activeProject. ngModel is bound to a property of this reference. So it's working, because a change in a component only update the property of the reference, and does not change the reference. You can even use a variable activeProject without wrapping it in a BehaviorSubject.
I know this should be in comment but this much of letters comment won't accept.
Forget about RxJS for a while.
Now you have getter and setter for your property.
You set activeProjectValue in your service.
Now when you subscribe it in one component, you will get the object which will be passed by reference. Same for the other component. As both components accessing same object they are passed by reference.
If you have to break the reference, to use it differently.
Also each component obtained what I thought was a copy of activeProject .... this means they copy by refenrence of object.
I know, you know how to break reference, but this is just for sake for future viewers
To break the reference of object you can use JSON.parse(JSON.stringify(*ObjectName*)
In your example
this.appProjectService.activeProject$.subscribe(activeProject => {
this.activeProject = JSON.parse(JSON.stringify(activeProject));
});

Vue.js Passing variable from one component to another (jQuery)

I have a component called ShowComment and a component called EditComment.
In ShowComment there is a variable this.CommentRecID. I want to use this variable in the component EditComment.
The problem is that a console.log(this.CommentRecID); shows that the variable is undefined in EditComment, but defined in ShowComment, but I don't know why it's undefined:
I used this to "use" this.CommentRecID in EditComment, but I don't know if this is the correct way to do it because it's related to jquery:
import * as $ from "jquery";
import DatePicker from "vue2-datepicker";
export default {
props: ["CommentRecID"],
components: { DatePicker },
Here's the full ShowComment component: https://pastebin.com/fcy4PCq0
Here's the full Editcomment component: https://pastebin.com/uik7EwD1
I'm fairly new to Vue.js. Does someone know how one can solve this issue?
You should not use jQuery and Vue.js at the same time.
You should try to use props to send data from parent to child.
You could add EditComment as an element in your ShowComment something like this:
<EditComment CommentRecID="this.CommentRecID" v-if="showEdit" />
And toggle the showEdit flag from the editItem method
editItem() {
this.showEdit = true
}
If you want to show a modal, then your EditComment component is probably up the tree so you could either use EventBus or use Vuex.
It seems like you are already using Vuex in your project, so add a mutation that stores the CommentRecID and use it in a similar manner to show the dialog.
You can use Vue Props to easily solve this problem, you have to send the variable from parent component to child component, please check this PROPS documentation out, its self explanatory:
Props Vuejs documentation
please let me know if you find trouble in using props

Vue: Reasons to use props instead of referencing parent data?

In VueJS, I have seen different ways of accessing parent properties from a component. Say I want to use the parent property items in my component.
First way
The component has a props value bound to a parent property:
.js
Vue.component("example", {
template: "<div></div>",
props: ["myItems"]
});
.html
<example v-bind:my-items="items"></example>
Second Way
The child component accesses a parent's properties directly, like this:
this.$parent.items
Question
Is there a reason to use the more elaborate first method over the second? Is there an overhead to "duplicating" data like that, vs. accessing it directly when needed?
The props should be mutated in the parent component, according to the official doc :
All props form a one-way-down binding between the child property and the parent one: when the parent property updates, it will flow down to the child, but not the other way around. This prevents child components from accidentally mutating the parent’s state, which can make your app’s data flow harder to understand.
In addition, every time the parent component is updated, all props in the child component will be refreshed with the latest value. This means you should not attempt to mutate a prop inside a child component. If you do, Vue will warn you in the console
So in order to update props from child component you should use this.$emit event and send the new value in order to handle the update in the parent one.

Categories