Vue.js component data not being updated after GET - javascript

I have a component that contains a default object, and on create GETs a populated object. When trying to bind this.profile to the new object it seems to get the correct data in the method but the change is not pushed back to other uses of this.profile. Is there a way to force this change to be picked up by the rest of the script?
export default {
data() {
return {
profile: {
firstName: 'Seller First Name',
surname: 'Seller Surname',
username: '',
biography: 'Seller biography.',
phoneNumber: 'Seller Phone Number',
emailAddress: 'Seller Email',
profilePhotoUrl: '',
testimonials: []
}
};
},
components: {
ProfileSummary,
Biography,
TestimonialList,
PaymentsenseCompany
},
created() {
console.log('created');
this.getProfile(this.$route.params.sellerUsername);
},
methods: {
getProfile(sellerUsername) {
axios.get('http://fieldsellerprofileapi.azurewebsites.net/api/fieldseller/' + sellerUsername)
.then(function(response) {
this.profile = Object.assign({}, response.data);
Vue.nextTick(() => {
console.log('after', this);
});
}.bind(this))
.catch(e => {
console.log(e);
// location.replace('/404');
});
}
},

Im not sure, but try this:
getProfile(sellerUsername) {
axios
.get('http://fieldsellerprofileapi.azurewebsites.net/api/fieldseller/' + sellerUsername)
.then(r => this.profile = r.data)
.catch(e => console.log(e))
}

So it turns out the issue wasn't that the values weren't being updated. They were being saved fine, I was just trying to access them in a child component which was not being updated with the parent for some reason. The changes were not propagating down to the children... This may be of use researching if you have the same issue.
Thanks

Related

Unexpected asynchronous action in "" computed property vue/no-async-in-computed-properties Vue3

I am developing my project with Vue3 , I am getting this error while running, here is my whole code . Can someone help me fix it. Thank you guys
<script>
import axios from 'axios';
export default {
name: "RegisterView",
data() {
return {
user: {
username: "",
password: "",
email: "",
phoneNumber: "",
role: "",
},
role : []
};
},computed:{
getRole(){
axios.get('http://localhost:8080/api/role/get').then(res=>{
this.role = res.data;
})
return [];
}
},
methods: {
register() {
axios.post("http://localhost:8080/api/user/register", this.user).then((res) => {
console.log(res.data);
});
},
},
};
</script>
// Error Unexpected asynchronous action in "getRole" computed property vue/no-async-in-computed-properties
I tried async and await , but it seems I got it wrong
Try to run that call inside the created hook :
import axios from 'axios';
export default {
name: "RegisterView",
data() {
return {
user: {
username: "",
password: "",
email: "",
phoneNumber: "",
role: "",
},
role : []
};
},
created(){
this.getRole():
},
methods: {
getRole(){
axios.get('http://localhost:8080/api/role/get').then(res=>{
this.role = res.data;
}).catch(err=>{
this.role = []
})
},
register() {
axios.post("http://localhost:8080/api/user/register", this.user).then((res) => {
console.log(res.data);
});
},
},
};
GetRole uses promises, meaning it doesn't have immediate value but has side-effects, which is considered to be dirty code by the linter (code quality checker)
If you need async computed, use asyncComputed instead, which has immediate value and gets updated of promise resolution automatically
https://github.com/foxbenjaminfox/vue-async-computed for Options API, #vueuse/core for Composition API

Vuex getter method returns undefined

I am trying to call a getter method and it's not getting called for some reason. If I console.log the store I can see that it's undefined:
This is where I'm calling the getter method:
computed: {
client() {
console.log(this.$store); //see above screenshot
console.log(this.$route.params.id); //shows a valid value.
//nothing seems to happen after this point, console.log in the below getter doesn't happen.
return this.$store.getters['clients/clientById', this.$route.params.id];
}
},
here's my getter in clients.js module:
getters: {
clients(state) {
return state.clients;
},
hasClients(state) {
return state.clients.length > 0;
},
clientById(state, id) {
console.log('test'); //this doesn't happen
return state.clients.find(client => client.id === id);
}
}
The first 2 getter methods are working fine, using the same syntax as what I'm doing when I'm calling the clientById getter.
What I'm trying to accomplish is to have an array of client objects, and then when a user clicks on a client in the client list, I grab the ID out of the route params and the appropriate client data is displayed on the page. I'd appreciate any guidance on whether I'm approaching this in the right way as well as I'm new to Vue.
state() {
return {
clients: [
{
id: null,
client_name: '',
address: '',
city: '',
state: '',
zip:'',
created_at: '',
updated_at: '',
deleted_at: null
},
]
};
},
UPDATE:
I'll provide my entire clients.js module in case something is off with that. Everything else seems to be working fine, so not sure if this is related or not. This is an updated version of the getter where I changed it to an arrow function based on your feedback. When I do this, I get another error: TypeError: 'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them at Function.
I've also tried hard-coding the ID within the getter method and taking it out of the passed-in ID parameter, and that seems to work, but is returning undefined, so it's still not getting a value from state.
import axios from "axios";
export default {
namespaced: true,
state() {
return {
isLoading: false,
clients: [
{
id: null,
client_name: '',
address: '',
city: '',
state: '',
zip:'',
created_at: '',
updated_at: '',
deleted_at: null
},
]
};
},
mutations: {
setLoadingStatus(state, status) {
state.isLoading = status;
},
setClients(state, clients) {
state.clients = clients;
}
},
actions: {
async fetchClients(context) {
context.commit('setLoadingStatus', true);
try {
const resp = await axios.get('http://localhost/api/clients');
context.commit('setLoadingStatus', false);
context.commit('setClients', resp.data);
} catch(e) {
console.log(e);
}
}
},
getters: {
clients(state) {
return state.clients;
},
hasClients(state) {
return state.clients.length > 0;
},
clientById: (state) => (id) => {
return state.clients.find(client => client.id === id);
}
}
};

How use a mutation function in a action function in Vuex?

I have this Vuex:
export default new Vuex.Store({
state: {
userInfo: {
nit_ID: { ID: '', Desc: '' },
userName: { ID: '', Desc: '' },
typeDocument: { ID: '', Desc: '' },
document: '',
},
globalPublicKey: 'ASDFGHJKL1234567890',
},
mutations: {
updateUserInfo(state, payload) {
state.userInfo = payload;
},
},
getters: {
userInfo: (state) => { return state.userInfo; },
},
actions: {
validateUserSession(context) {
var valido = false;
try {
let storageInfo = JSON.parse(
sjcl.decrypt(context.state.globalPublicKey, localStorage.userInfo)
);
if (localStorage.userToken === storageInfo.token) {
context.mutations.updateUserInfo(storageInfo);
valido = true;
}
} catch (e) {
console.error(e);
}
return valido;
},
},
})
But the problem is that I can't access to the mutation updateUserInfo(), I know that is easy to solved, only do the updateUserInfo process in my action, but the question is How can I use a mutation into a action?
In VueJS you can call a mutation from an action by calling context.commit, like this:
context.commit('mutationName', params)
params can be omitted if not parameters are passed to the mutation.
More on this here: vuex.vuejs.org/guide/actions.html
Actually you call a mutation from anywhere with a commit - but it's advised to use actions (so dispatch an action) that in turn commits the data (actually mutates the state).

How to setState of this nested object?

Hi Im having troubles setting the state when I press a button 'Send' on one email input.
I'm trying it avoiding mutation as React docs recommends.
My state properties are this:
state = {
emailForm: {
email: {
elementType: 'email-invitation-input',
elementConfig: {
type: 'email',
placeholder: 'Enter an email..',
},
value: '',
valid: true,
required: true
}
},
requestStatus : false,
validationMessage : null,
formIsValid: false,
}
So I tried three ways to set empty value to my email input trough the state but no one worked :(
First try:
I used ES6 spread operator to change it value but it doesn't change the input value:
this.setState({
email: {
...this.state.emailForm.email,
value: '',
},
});
this.setState({
email: Object.assign({}, this.state.emailForm.email, {
value: '',
}),
});
Another try using immutability-helper package
import update from 'immutability-helper';
let newData = { email: {
...this.state.emailForm.email,
value: '',
}, };
this.setState({
email: update(this.state.newData, {
value: {$set: newData},
})
});
Second try:
I used Ramda.js but it neither works.
setObjectByPath(fieldPath, value) {
this.setState({
emailForm: R.set(R.lensPath(fieldPath), value, this.state.emailForm)
})
}
setObjectByPath(this.state.emailForm.email,'');
Third try:
I used react-addons-update:
import update from 'react-addons-update';
this.setState({
email: update(this.state.newData, {
value: {$set: newData},
})
});
All tries does nothing or it creates a new email input with empty value below.
Thanks beforehand
this.setState(prevState => ({
emailForm: {
email: {
...prevState.emailForm.email,
value: ''
}
}
}));

(Multiple) Axios Post requests/params question

This is a multipart question (and coincidentally my first here on Stack!). To preface, I'm building a site with a Rails backend and a Vue.js frontend.
My problem is with an Axios POST request. I am attempting to send two POST requests with one click of the submit button. I have a "Trips" controller and a "User_Trips" controller - the later of which functions as a join to other tables in my database. In order for a newly created trip to show up, a new user_trip needs to be created too.
My trip posts just fine and shows up when I look for it in Postico, but my user_trip does not post successfully, and I think it's because I'm struggling to determine how to pass the recently created trip's id through as the param needed to create a user_trip. Here is a section of the code I'm working on from Vue.js:
<script>
import axios from "axios";
export default {
data: function() {
return {
trips: [],
errors: [],
name: "",
country: "",
state: "",
city: "",
postal_code: "",
start_date: "",
end_date: "",
image: "",
trip: this.trip
};
},
mounted: function() {
// axios.get("http://localhost:3000/api/trips").then(
// function(response) {
// console.log(response);
// this.trips = response.data.trips;
// }.bind(this)
// );
},
methods: {
submit: function() {
var params = {
name: this.name,
country: this.country,
state: this.state,
city: this.city,
postal_code: this.postal_code,
start_date: this.start_date,
end_date: this.end_date,
image: this.image
};
axios
.post("http://localhost:3000/api/trips", params)
.then(response => {
axios.get("http://localhost:3000/api/trips").then(
function(response) {
console.log(response);
this.trips = response.data.trips;
}.bind(this)
);
})
.catch(error => {
this.errors = error.response.data.errors;
});
var paramsTwo = {
trip_id: this.trip.id
};
axios
.post("http://localhost:3000/api/usertrips", paramsTwo)
.then(response => {
this.$router.go("/home");
})
.catch(error => {
this.errors = error.response.data.errors;
});
}
}
};
</script>
Here is the error message I receive in the console log:
Uncaught TypeError: Cannot read property 'id' of undefined and I'm thinking it's because I'm not selecting the right trip from the array...BUT when I look at the GET request in the log, the newly created trip doesn't show up - it's only visible my database. Any helpful suggestions are most appreciated!!
- Thanks
Figured it out! A big thanks to the helpful commenters and answerers.
<script>
import axios from "axios";
export default {
data: function() {
return {
trips: [],
errors: [],
name: "",
country: "",
state: "",
city: "",
postal_code: "",
start_date: "",
end_date: "",
image: "",
};
},
mounted: function() {
},
methods: {
submit: function() {
var params = {
name: this.name,
country: this.country,
state: this.state,
city: this.city,
postal_code: this.postal_code,
start_date: this.start_date,
end_date: this.end_date,
image: this.image
};
axios
.post("http://localhost:3000/api/trips", params)
.then(response => {
console.log(response);
this.trip = response.data;
var paramsTwo = {
trip_id: this.trip.id
};
axios
.post("http://localhost:3000/api/usertrips", paramsTwo)
.then(response => {
this.$router.go("/home");
})
.catch(error => {
this.errors = error.response.data.errors;
});
}
);
}
}
};
</script>
The code is breaking at the paramsTwo line and that's why your second post won't work. Make sure that the object returned by your API has an id property. Some DBs return a _id property instead of id.

Categories

Resources