Variable Doesn't Change in Vue.js - vue.js

I can't change the variable qty in my computed properties.
getQuantity(){
return (qtyId) => {
var qty = 0;
axios.get( window.location.origin + '/api/quantity/' + qtyId)
.then(res => {
console.log(res.data.qty)
qty = res.data.qty
})
.catch()
console.log(qty)
return qty
}
},
It is an asynchronous request using axios. the console.log(res.data.qty) works fine it output 4 but the console.log(qty) is 0. I think it's because of asynchronous request... How can I make it work... TY

I think it's because of asynchronous request
It definitely is.
If you're not familiar with writing asynchronous code, I would read up on that first (in particular promises).
console.log(qty) returns 0 because that code is executed immediately after the request is sent and before the response has come back from the server. The callback function you passed to then is the function that will be executed once the response has come back from the server, and only then will you be able to obtain qty from the response data.
If you want to return qty from that function (which is what it looks like you are trying to do), then that function must return a promise that once resolved will contain the qty value (code isn't blocked in JavaScript, hence the reason for the promise).
getQuantity() {
return (qtyId) => {
return axios.get(window.location.origin + '/api/quantity/' + qtyId)
.then(res => {
return res.data.qty;
});
}
},
Why is it a computed property instead of a method? I think a different approach would be better, but I don't know exactly how this code fits into your project.

Related

Unable to make a sequential service (HTTP) calls in Angular 5 by using Joins

I had a Array with N number of objects. I want to make a service call sequentially. One response comes based on that i will make a another request. Please provide a better approach to handle this scenario through JOINS in Angular 5.
You can use switchMap for this.
nestedCalls(user: any) {
return this.http.get('YOUR_URL').pipe(
switchMap(data => {
const body = {
// do your work woth data - first service object
};
return this.http.post('YOUR_URL', body);
})
)
}
Or you can do something like below also :
this.service.getData(id, (response) => {
this.service.getInitiatedEntity(response.id).subscribe(
(retData) => {
// response - 1st service data
// retData - 2nd service data
}
);
});
Hope this help.

How to access the current instance in nuxt page validate()?

I return a Promise in validate(). Now, I want to pass the data which is returned in the validation by the server to one of the methods. However, I am not able to do this. Please help!
validate({ params, store, context }) {
return store.dispatch(types.VALIDATE_PARAMS_ASYNC, params.id).then(data => {
this.saveSettings(this, data)
return true
}).catch(e => {
return false
})
}
Its not possible. Validate executed before the instance initialized, so you cant access methods. And validate isnt supposed to be used that way.
For passing data to need either to save them into vuex store ( preferably in fetch method ) or return them as data in asyncData method. Then you can do what you want with your data in for example mounted method, or beforeMounted.

Angular multiple rest api request

im new on Angular and have a question.
I need to call 2 API Rest, on second API i need result of first API.
I have this code:
ngOnInit() {
this.Jarwis.getmyinfo()
.subscribe(
// data => console.log(data),
data => this.Getmyinfo = data,
error => console.log(error),
);
this.Jarwis.showazienda(id_azienda).subscribe(
// data => console.log(data),
data => this.Showazienda = data,
error => console.log(error),
);
}
This is a call to API rest in Jarwis:
getmyinfo(): Observable {
return this.http.get(${this.baseUrl}/me);
}
showazienda(data): Observable {
return this.http.get(${this.baseUrl}/showazienda/ + data);
}
getmyinfo is first HTTP REQUEST and where i need to get id_azienda for second HTTP REQUEST (showazienda)
I think need map result of first http request in json and get result of id_azienda but im not able to do it.
If i set 1 in the parameters of showazienda im able to get and show info of API.
For observables, you use the ".flatMap" to chain multiple async actions together (this is very similar to the promises ".then"). The flatMap allows you to used to chain multiple async requests together and have them execute one by one in order.
Here is a good explanation of flatMap.
So for your example, you would do something like this:
ngOnInit() {
this.Jarwis.getmyinfo()
.flatMap(
(data) => {
this.Getmyinfo = data;
// get id_azienda from data
return this.Jarwis.showazienda(id_azienda);
}
).subscribe(
// data => console.log(data),
data => this.Showazienda = data,
error => console.log(error),
);
}
This example code will first send the "getmyinfo()" request. Once the response is received the ".flatMap" will be called with the data received from "getmyinfo()". You can then used this data to get the "id_azienda". Then you can make the second request to "showazienda". The observable returned from "showazienda()" needs to be returned in the flatMap. Then you subscribe to the modified observable and the data you receive will be the result from the "showazienda()" request.

FETCH API return undefined

I want to use Fetch API but i don' t really understand it's mecanism.
I have an in my HTML and i want to assign the result of my fetch with this code :
const weather = "http://api.apixu.com/v1/current.json?key=cba287f271e44f88a60143926172803&q=Paris";
const array = [];
fetch(weather)
.then(blob => blob.json())
.then(data => {
array.push(data.current.humidity)
console.log(array[0])
}
);
document.querySelector('h1').innerHTML = array[0];
i have the result with the console.log but the returns "undefined". can you explain why ?
thanks a lot
This is because the call to the API is asynchronous, meaning that the code is not executed just line by line as you write it. The callback only runs as soon as the call to the API has finished, basically meaning that
data => {
array.push(data.current.humidity)
console.log(array[0])
}
runs after
document.querySelector('h1').innerHTML = array[0];
So when you try to set your h1, array is still empty. If you want to set it as soon the data is available, you have to do it within the callback function:
data => {
array.push(data.current.humidity)
document.querySelector('h1').innerHTML = array[0];
}
This might seem weird at first, but keep in mind that you're only registering an anonymous function but not running it yet. You just define the function that you want to trigger as soon as something happens, in this case: when your API call has finished.

Dojo datagrid jsonrest response headers

I'd like to use custom headers to provide some more information about the response data. Is it possible to get the headers in a response from a dojo datagrid hooked up to a jsonRest object via an object store (dojo 1.7)? I see this is possible when you are making the XHR request, but in this case it is being made by the grid.
The API provides an event for a response error which returns the response object:
on(this.grid, 'FetchError', function (response, req) {
var header = response.xhr.getAllResponseHeaders();
});
using this I am successfully able to access my custom response headers. However, there doesn't appear to be a way to get the response object when the request is successful. I have been using the undocumented private event _onFetchComplete with aspect after, however, this does not allow access to the response object, just the response values
aspect.after(this.grid, '_onFetchComplete', function (response, request)
{
///unable to get headers, response is the returned values
}, true);
Edit:
I managed to get something working, but I suspect it is very over engineered and someone with a better understanding could come up with a simpler solution. I ended up adding aspect around to allow me to get hold of the deferred object in the rest store which is returned to the object store. Here I added a new function to the deffered to return the headers. I then hooked in to the onFetch of the object store using dojo hitch (because I needed the results in the current scope). It seems messy to me
aspect.around(restStore, "query", function (original) {
return function (method, args) {
var def = original.call(this, method, args);
def.headers = deferred1.then(function () {
var hd = def.ioArgs.xhr.getResponseHeader("myHeader");
return hd;
});
return def;
};
});
aspect.after(objectStore, 'onFetch', lang.hitch(this, function (response) {
response.headers.then(lang.hitch(this, function (evt) {
var headerResult = evt;
}));
}), true);
Is there a better way?
I solved this today after reading this post, thought I'd feed back.
dojo/store/JsonRest solves it also but my code ended up slightly different.
var MyStore = declare(JsonRest, {
query: function () {
var results = this.inherited(arguments);
console.log('Results: ', results);
results.response.then(function (res) {
var myheader = res.xhr.getResponseHeader('My-Header');
doSomethingWith(myheader);
});
return results;
}
});
So you override the normal query() function, let it execute and return its promise, and attach your own listener to its 'response' member resolving, in which you can access the xhr object that has the headers. This ought to let you interpret the JsonRest result while fitting nicely into the chain of the query() all invokers.
One word of warning, this code is modified for posting here, and actually inherited from another intermediary class that also overrode query(), but the basics here are pretty sound.
If what you want is to get info from the server, also a custom key-value in the cookie can be a solution, that was my case, first I was looking for a custom response header but I couldn't make it work so I did the cookie way getting the info after the grid data is fetched:
dojo.connect(grid, "_onFetchComplete", function (){
doSomethingWith(dojo.cookie("My-Key"));
});
This is useful for example to present a SUM(field) for all rows in a paginated datagrid, and not only those included in the current page. In the server you can fetch the COUNT and the SUM, the COUNT will be sent in the Content-Range header and the SUM can be sent in the cookie.