Reputation: 487
I am using 2 API Points. First one is to get all the exchanges and the second to print the BTC price on every exchange from the first point. I then want to combine both calls to 1 Object
var app = angular.module("App", []);
app.controller("Ctrl", function ($scope, $http) {
var rand = [];
$http({
method: "GET",
url: "https://min-api.cryptocompare.com/data/all/exchanges"
}).then(function success(response) {
var datas = response.data;
for (var prop in datas) {
$http.get("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=USD&e=" + prop)
.then(function success(responsePrice) {
rand.push({'exchange' : prop, 'price' : responsePrice.data});
})
}
});
console.log(rand);
});
API points are working fine if i dont put them together. Is it bad to have a loop in my http get? Seems that i have no scope after the success function, so prop is always displayed as the last exchange. Would be very thankful for help. Thanks
Upvotes: 1
Views: 54
Reputation: 10071
try this
var app = angular.module("App", []);
app.controller("Ctrl", function ($scope, $http) {
var rand = [];
$http({
method: "GET",
url: "https://min-api.cryptocompare.com/data/all/exchanges"
}).then(function success(response) {
var datas = response.data;
var keys = Object.keys(datas);
var promises = keys.map(prop =>
$http.get("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=USD&e=" + prop));
Promise.all(promises).then((response) => {
rand = response.map((responsePrice, index) => {
return {
'exchange': keys[index],
'price': responsePrice.data
};
});
console.log(rand);
}).catch((err) => {
console.log(err);
});
});
});
Upvotes: 0
Reputation: 1579
Your scope for prop
will always be lost because of async
task in the loop. To retain the scope of prop
you have to use let
instead of var
because var
have function
scope and and let
have block
scope. So your modified code will be as
var app = angular.module("App", []);
app.controller("Ctrl", function ($scope, $http) {
var rand = [];
$http({
method: "GET",
url: "https://min-api.cryptocompare.com/data/all/exchanges"
}).then(function success(response) {
var datas = response.data;
for (let prop in datas) {
$http.get("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=USD&e=" + prop)
.then(function success(responsePrice) {
rand.push({'exchange' : prop, 'price' : responsePrice.data});
})
}
});
console.log(rand);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
Upvotes: 1
Reputation: 2534
Yes, your following loop has problem:
for (var prop in datas) {
$http.get("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=USD&e=" + prop)
.then(function success(responsePrice) {
rand.push({'exchange' : prop, 'price' : responsePrice.data});
})
}
The line for (var prop in datas) {
executes all of its iteration and
points to the last element before finish the $http.get
request as its
asynchronous request.
So, to achieve this, some mechanism need to ensure the valid data
present at the time of $http.get
call.
Now to do this, an array has been created by using the following code as the return value is a map and its difficult to use in next recursive function:
datas = response.data;
console.log(datas);
for (var prop in datas) {
propArray.push(prop);
}
The following recursive function ensures the value of your used prop
item updated after each $http.get
has been completed:
var dataAcquireLoop = function () {
dataIndex++;
if(dataIndex >= propArray.length) {
console.log(rand);
return;
}
console.log(propArray[dataIndex]);
$http.get("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=USD&e=" + propArray[dataIndex])
.then(
function success(responsePrice) {
rand.push({'exchange' : propArray[dataIndex], 'price' : responsePrice.data});
dataAcquireLoop();
},
function(error) {
dataAcquireLoop();
}
);
}
The final updated code given below:
app.controller("Ctrl", function ($scope, $http) {
var rand = [];
var datas = [];
var dataIndex = -1;
var propArray = [];
var dataAcquireLoop = function () {
dataIndex++;
if(dataIndex >= propArray.length) {
console.log(rand);
return;
}
console.log(propArray[dataIndex]);
$http.get("https://min-api.cryptocompare.com/data/pricemulti?fsyms=BTC&tsyms=USD&e=" + propArray[dataIndex])
.then(
function success(responsePrice) {
rand.push({'exchange' : propArray[dataIndex], 'price' : responsePrice.data});
dataAcquireLoop();
},
function(error) {
dataAcquireLoop();
}
);
}
$http({
method: "GET",
url: "https://min-api.cryptocompare.com/data/all/exchanges"
}).then(function success(response) {
datas = response.data;
console.log(datas);
for (var prop in datas) {
propArray.push(prop);
}
dataAcquireLoop();
});
});
Upvotes: 0