Pass Response Value in Vue Component - vue.js

i already call the axios and show using console log if it is successful or not already, However i wanted to pass the axios post response value to my vue component and display the response in my vue component in order for me to make a condition. Is there any way to do it? I try some other part but no luck. Kindly guide me.
main.vue
methods: {
onClicked() {
this.$store
.dispatch('Clickme', this.data)
.then(() => {
alert("Success");
})
.catch(() => {
alert("Error");
})
}
}
clicked.js
return new Promise((resolve, reject) => {
clicked(username, password)
.then(resp => {
console.log("---->>>> : ");
const data = resp.data.data
console.log(username, password);
console.log(resp);
console.log("statresponse.status : " + resp.data.status);
console.log("statresponse.message : " + resp.data.message);
console.log("statresponse.inside message : " + resp.data.data.message);
// console.log("USER.JS RESPONSE: " + resp.data.status);
// console.log("USER.JS RESPONSE: " + resp.data.message);
setToken(data.token)
commit('SET_TOKEN', data.token)
resolve()
})
.catch(error => {
console.log(error)
reject(error)
})
})

Try changing main.vue to:
onClicked() {
this.$store
.dispatch('Clickme', this.data)
.then((response) => {
//Do whatever you want with your response
alert("Success");
})
.catch(() => {
alert("Error");
})
}
and change clicked.js to:
resolve(resp.data.data)
This will make so the promise resolves the response data.
However if you make the http request in your store/using vuex, what you probably want to do is commit a mutation to put the response into your state - and then map the state from your component.

Related

Send data from component to Vuex

I have a component file in which I send id using dispatch:
mounted() {
const warehouseId = this.$route.params.id;
this.$store.dispatch("showWarehouse", {warehouseId}).then(() => {
this.warehouseData = this.$store.state.showWarehouses;
});
},
I get id of element from route (warehouseId), next I run action showWarehouse.
In store.js (Vuex) file I have an action:
showWarehouse({ commit }, payload) {
return new Promise((resolve, reject) => {
axios.get('/api/warehouse/' + payload)
.then(response => {
commit('showWarehouse', response.data);
resolve();
})
.catch(error => {
console.warn(error);
});
});
}
I try get id from componnt using payload, but probably this value is undefined. When I change:
axios.get('/api/warehouse/' + payload)
to
axios.get('/api/warehouse/1')
axios return correctly data from database.
Ok, I found a solution
I must just add payload.warehouseId:
axios.get('/api/warehouse/' + payload.warehouseId)
warehouseId must been this the same name from a component:
this.$store.dispatch("showWarehouse", {warehouseId})

Return to request after refreshing tokens

I am trying to get refresh tokens working.
It works for the most part, but the problem is I'm not sure how to return to where the original call was before the access token needed refreshing.
It doesn't work the first time it refreshes, after that the token is refreshed and then it works ok again until it expires.
So the problem is I cant get it returning to where it started on the refresh
Here is an example from the component
created(){
axios.get("http://localhost:63861/api/sampledata/WeatherForecasts").then(response => {
console.log(response.data);
//**** DO STUFF WITH THE DATA. I WANT TO GET BACK HERE AFTER REFRESH
})
.catch(error => {
console.log(error);
});
I need to get back to the point where it can do stuff with the data once it has refreshed and reset the access tokens.
my interceptor:
import axios from "axios";
import store from "../store";
import Storage from "../services/storage";
import { REFRESH } from "../store/actions.type";
export default function execute() {
// Request
axios.interceptors.request.use(
config => {
var token = Storage.getAccessToken();
if (token) {
console.log("Bearer " + token);
config.headers["Authorization"] = "Bearer " + token;
}
return config;
},
error => {
return Promise.reject(error);
}
);
// Response
axios.interceptors.response.use(
response => {
return response;
},
error => {
console.log("Error need to refresh");
const originalRequest = error.config;
// token expired
if (error.response.status === 401) {
originalRequest._retry = true;
let tokenModel = {
accessToken: Storage.getAccessToken(),
client: "Web",
refreshToken: Storage.getRefreshToken()
};
var refreshPath = "auth/" + REFRESH;
store
.dispatch(refreshPath, { tokenModel })
.then(response => {
console.log(response);
return axios(originalRequest);
})
.catch(error => {
console.log(error);
// Logout
});
}
return Promise.reject(error);
}
);
}
You need to return your refresh promise.
return store
.dispatch(refreshPath, { tokenModel })
.then(response => {
console.log(response);
return axios(originalRequest);
})
.catch(error => {
console.log(error);
// Logout
});
What is happening now is you dispatch the action, then your return Promise.reject(error) is ran. By returning the refresh promise, you ensure axios waits for that chain to finish

Vue returning from a promise

I am trying to return some value from this dispatch
this.$store.dispatch('setValue', this.Value)
.then(response => {
console.log(response)
});
In my vuex action I have
.catch(error => {
if (error.response.status === 412) {
return "some message"
}
});
How can I pass the error back to the .vue file where the vuex dispatch is made?
I think the correct way of doing this is to have a status property in your store.
Your status object would consist out of error, success, loading.
So if your action throw exception you can handle it like this:
catch (error) {
commit("error", `Some Message`);
}
Your error mutation would look like this:
error(state, payload) {
state.status.success = false;
state.status.loading = false;
state.status.error = payload || false;
}
Your template would just listen on the store.state.status
<div v-if="store.state.status.error">{{store.state.status.error}}</div>
I might be wrong but in my personal opinion I feel it is wrong to use actions to return stuff. Your using the store so might as well leverage it best you can.
Other extra benefits is, you can indicate to your .vue file if api is loading or when something is successful.
What I ended up doing was pretty simple. I chained the catch to my dispatch:
this.$store.dispatch('setValue', this.Value)
.then(response => {
console.log(response)
})
.catch(error => {
if (error.response.status === 412) {
return "some message"
}
});
Then I returned the Axios call from the action:
return axios({
method: 'post',
url: `/mypath,
data: mydata,
json: true,
})
This means I could deal with the returned data/errors locally where I wanted to trigger an action.
Store:
.catch(error => {
if (error.response.status === 412) {
throw error
}
});
Vue element with async method:
try{
let response = await this.$store.dispatch('setValue', this.Value)
} catch(error) {
console.log(error)
});

React Native fetch doesn't work in another fetch callback

If I call my api function from POINT 1, fetch method inside the api method works well. When I comment it out and call the function at POINT 2 fetch method inside the addAccount() doesn't work. There is no exception, no rejection, no request on Reactotron, even I can't find request over Charles Proxy. What is the difference and what I have to know to figure it out?
I tried with RN 0.55.2 and 0.57.5
// Auth.js typical react native component
import * as api from '../actions/api';
class Auth extends Component {
// first triggered function
loginAccount(){
// api.addAccount(); // POINT 1 - this line works well if I uncomment
fetch('https://domain-a.com/login/',{
method: 'POST',
credentials: "same-origin",
headers: {
'accept-language': 'en-US;q=1',
'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
},
body: encodeURIComponent(bodyParameters)
}).then((response) => {
console.log(response);
return response.json()
}).then(({ status, invalid_credentials }) => {
if(status == "ok"){
CookieManager.get('https://domain-a.com')
.then((cookies) => {
this.fetchAccountData(cookies);
})
})
}
fetchAccountData(cookies){
fetch('https://domain-a.com/'+cookies.user_id+'/info/',{
method: 'GET',
headers: {
'cookie': cookies
}
}).then((response) => {
return response.json();
})
.then(({ user, status }) => {
api.addAccount(); // POINT 2 - this line doesn't work
});
}
}
// api.js
// I repleaced fetch code with document example just to be clearify
export const addAccount = () => {
console.log("fetch begin"); // always works
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => response.json())
.then((responseJson) => {
console.log(responseJson); // won't works from point 2
})
.catch((error) =>{
console.error(error); // never runs
});
}
It looks like your first .then statement in the addAccount() function is missing a return statement. responseJson would be undefined without a proper a 'return response.json()' statement. Also adding brackets for better semantic formatting.
export const addAccount = () => {
console.log("fetch begin"); // always works
fetch('https://facebook.github.io/react-native/movies.json')
.then((response) => {
console.log(response); //test this response
return response.json();
})
.then((responseJson) => {
console.log(responseJson); // won't works from point 2
})
.catch((error) =>{
console.error(error); // never runs
});
}

Access vuex store from catch block

Im trying to put error messages from an api call and put it in the vuex store, but im not sure how to do it.
I have this in a "method" within a vue file
axios
.post("/api/model", this.model)
.then(response => {
window.location.href = "/Home/Index";
})
.catch(function(error) {
if (error.response) {
this.$store.commit("setServerErrors", error.response.data);
}
});
Im getting the following error:
Uncaught (in promise) TypeError: Cannot read property '$store' of undefined
Probably your function is reassigning the value of this.
Try changing it to:
axios
.post("/api/model", this.model)
.then(response => {
window.location.href = "/Home/Index";
})
.catch(error => { // <= HERE IS THE CHANGE!!
if (error.response) {
this.$store.commit("setServerErrors", error.response.data);
}
});
Read about the difference between function(arg) {}and (arg) => {}here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
You are using a function instead of an arrow function on the catch block so this inside that block has a different scope.
Just replace the function with an arrow function.
axios
.post("/api/model", this.model)
.then(response => {
window.location.href = "/Home/Index";
})
.catch((error) => {
if (error.response) {
this.$store.commit("setServerErrors", error.response.data);
}
});