[英]Error passing arguements between promises in AngularJS
I'm building a promise chain which contains four functions. 我正在构建一个包含四个功能的承诺链。 The purpose of the promise is to make a few API calls.
许诺的目的是进行一些API调用。 Each API call affects the following one, and some require multiple arguments.
每个API调用都会影响以下调用,某些调用需要多个参数。
The basic flow of the code below is this: 下面的代码的基本流程是这样的:
geocodeLocation
is the first function, and takes the $scope.location
input which gets geocoded into the result
object containing lat
, lng
, and formattedAddress
geocodeLocation
是第一个函数,并接受$scope.location
输入,该输入将被地理编码到包含lat
, lng
和formattedAddress
的result
对象中 getSearchCount
is the second function that requires the result
from the previous function. getSearchCount
是第二个函数,需要上一个函数的result
。 This function queries the API using Restangular and returns a plucked_result
object. plucked_result
对象。 saveLocation
function requires both the result
and plucked_result
to create a new location, based on whether plucked_result.search_count
is less than 1
or not. saveLocation
函数根据plucked_result.search_count
是否小于1
,需要result
和plucked_result
来创建一个新位置。 The search_count
variable is returned by this function. search_count
变量。 getPhotos
requires the result
and search_count
arguments. getPhotos
需要使用result
和search_count
参数。 Using these it builds a an API request URL that gets fired off. photos
are saved to the db. photos
将保存到数据库。 The error occurs within the saveLocation
function. 该错误发生在
saveLocation
函数中。 The error being returned is: 返回的错误是:
TypeError: Cannot read property 'search_count' of undefined
Here's the code (with a few comments on what's going on): 这是代码(对正在发生的事情有一些评论):
var geocodeLocation, getPhotos, getSearchCount, saveLocation;
// geocode the $scope.location into a formatted address with latitude and longitude
geocodeLocation = function(location) {
return Geocoder.geocodeAddress(location).then(function(result) {
$scope.geocodingResult = "(lat, lng) " + result.lat + ", " + result.lng + " (address: '" + result.formattedAddress + "')";
console.log(result);
// pass the result object from the previous function into the next function
return result;
});
};
getSearchCount = function(result) {
// fetch the locations from the API (using Restangular)
return Global.locationsRoute().getList().then(function(data) {
var plucked_result;
// use underscore's _findWhere to pluck out the location we're looking for, and extract it's search_count
plucked_result = _.findWhere(data, {
name: result.formattedAddress
});
// this is logging correctly
console.log(plucked_result);
return plucked_result;
});
};
saveLocation = function(plucked_result, result) {
var newLocation, search_count;
// this is logging incorrectly, and is where the error occurs
search_count = plucked_result.search_count;
console.log(search_count);
// if the search_count is more than 1, increment and update the search_count
if (!(search_count < 1)) {
plucked_result.search_count = search_count + 1;
} else {
// if the search_count is less than 1, create a new location
newLocation = {
name: result.formattedAddress,
lat: result.lat,
lng: result.lng,
search_count: 1
};
Global.locationsRoute().post(newLocation);
}
return search_count;
};
// this function requires both the result and search count to build the 500px API request string
getPhotos = function(result, search_count) {
var newUrl, url;
url = Global.externalAPI() + "search?geo=" + result.lat + "," + result.lng + ",25km&rpp=5&image_size=4&tags=true&sort=votes_count&only=[Landscapes][City+%26+Architecture][Nature][Urban+Exploration][Underwater][Travel][Journalism][Black+and+White]&page=" + search_count + "&consumer_key=" + Global.consumerKey();
newUrl = Restangular.oneUrl('500px', url).get();
return newUrl.then(function(data) {
var newPhoto, photo, _i, _len, _ref, _results;
$scope.photos = data;
_ref = data.photos;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
photo = _ref[_i];
newPhoto = {
name: photo.name,
description: photo.description,
image_url: photo.image_url,
search_term: result.formattedAddress
};
_results.push(Global.photosRoute().post(newPhoto));
}
return _results;
});
};
$scope.geocode = function() {
var location;
if ($scope.location) {
location = $scope.location;
return geocodeLocation(location).then(getSearchCount).then(saveLocation).then(getPhotos);
}
};
The question here is: how do I pass the result
, plucked_result
and search_count
variables between all the functions? 这里的问题是:如何在所有函数之间传递
result
, plucked_result
和search_count
变量?
Solved. 解决了。 Promises can't pass more than one argument between them, so you need to bundle all of your objects and variables into an array, and pass that array between the functions.
承诺之间不能传递多个参数,因此您需要将所有对象和变量捆绑到一个数组中,并在函数之间传递该数组。 For example:
例如:
var getSearchCount, saveLocation;
getSearchCount = function(result) {
return Global.locationsRoute().getList().then(function(data) {
var passed_data, plucked_result;
plucked_result = _.findWhere(data, {
name: result.formattedAddress
});
passed_data = [result, plucked_result];
return passed_data;
});
};
saveLocation = function(passed_data) {
var newLocation, plucked_result, result, search_count;
result = passed_data[0];
plucked_result = passed_data[1];
search_count = plucked_result.search_count;
if (!(search_count < 1)) {
plucked_result.search_count = search_count + 1;
plucked_result.put();
} else {
newLocation = {
name: result.formattedAddress,
lat: result.lat,
lng: result.lng,
search_count: 1
};
Global.locationsRoute().post(newLocation);
}
passed_data = [result, search_count];
return passed_data;
};
Where passed_data
is an array containing the objects and variables. 其中
passed_data
是包含对象和变量的数组。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.