I'm trying to use the jQuery when function, in order to wait until an Ajax request completes before proceeding onwards, but am clearly getting something wrong.
My console output looks like this:
geocodeMaster
geocode Canary Wharf
Object
geocode
Object
address is blank, returning 51.501885 -0.190894
proceeding
Uncaught TypeError: Cannot read property '0' of undefined
Object
Object
The final two Objects are the output from the second call to geocode. Why does the code show proceeding before the output of the second call?
My code looks like this:
function geocode(address, geodata) {
console.log('geocode', address, geodata);
geodata['street'] = address;
if (address=="") {
console.log('address is blank, returning ' + current_latlng[0], current_latlng[1]);
return [current_latlng[0], current_latlng[1]];
}
$.ajax({
url: CS_API + 'geocoder.json',
data: geodata,
dataType: 'jsonp',
jsonpCallback: 'places',
success: function(from_data) {
console.log(from_data);
if (from_data.results.result!=undefined){
var from_result = from_data.results.result;
console.log(from_result)
return [from_result.latitude, from_result.longitude];
} else {
return false;
}
},
error: function(data) {
return false;
}
});
}
function geocodeMaster(place_from,place_to) {
console.log('geocodeMaster');
geodata['key'] = CS_API_KEY;
if (current_latlng!=null) {
geodata['n'] = current_latlng[0] + 0.1;
geodata['e'] = current_latlng[1] + 0.1;
geodata['s'] = current_latlng[0] - 0.1;
geodata['w'] = current_latlng[1] - 0.1;
}
var start_coords,finish_coords;
$.when(start_coords=geocode(place_from,geodata),finish_coords=geocode(place_to,geodata)).then(function(){
console.log('proceeding');
console.log(start_coords[0],start_coords[1],finish_coords[0],finish_coords[1]);
});
}
Is the problem that the objects supplied to when() are not Deferred objects? If so, how can I make them into Deferred objects, while keeping the information that I need to collect - start_lat, etc?
You must return a deferred object from the geocode function. Try :
return $.ajax(..
You cannot store the return value directly into values (it does not work the way it's written now). You have to store them somewhere else, so that the line that calls the when simply reads :
$.when(geocode(place_from,geodata),geocode(....
To solve this, you could pass to geocode an empty object, and have that function save its result in it, for example :
var start_coords = {};
var finish_coords = {};
$.when(geocode(place_from,geodata,start_coords),geocode(place_to,geodata,finish_coords) ...
Related
I have a javascript which is like this
function one (var1, var2){
var var3= var1+var2;
return var3;
}
function two( var4, var5){
var var6=var4*var5;
return var6;
}
function three(var7, var8){
var9=var7/var8;
return var9;
}
var first = one(2, 4);
var second= two(first, 8);
var third= three(second, 9);
I want all the function to be separate because they each are like module which would handle different operations. So I do not want to use callback, I have tried
$.ajax(first = one(2,4))
.then({second=two(first, 8)})
.then(three(second,9))
I have also tried this
$.ajax()
.then(function(first=one(2,4){
return first;
})
.then(function(second=two(first,4){
return second;
})
I have also tried this
$.ajax({
first:one(2,4),
second:two(first,4),
third:three(second,9),
})
.then(function(first=one(2,4){
return first;
})
.then(function(second=two(first,4){
return second;
})
this may sound funny but I even tried
var third= three(two(one(2, 4), 8), 9);
amongst many others.
All of them show operation takes place with the first function and other functions but the it does not give me result from previous function
This is an update to the above.
Modification
I do not want to use promise in the other functions as some other functions would also call those functions and they would not be expecting a promise but a valid data
function modifyData(details){
for(var x=0 ;x<array.length;x++){
//this would do a massive loop which would
//return a json string that would be
}
}
function tableFunction(url, tableNameVar){
//json fields
var details=[];
details[0] = 'name';
details[1] = 'sex';
details[2] = 'eye_color';
details[3] = 'height';
details[4] = 'body_built';
var jsonData='';
var main = "";
$(document).ready(function(){
$('#'+tableNameVar+'').dataTable({
destroy: true,
data: JSON.parse(extraFunctionProcess(modifyData(details),details)),
columns:[
{title: "Name", data:"name"} ,
{title: "Gender", data:"sex"} ,
{title: "Eye color", data:"eye_color"} ,
{title: "Height", data:"height"} ,
{title: "Body built", data:"body_built"}
]
});
});
}
I want to process the data and put it inside the table. The extraFunctionProcess has worked if the data is passed
straight into the data field without putting it inside the modifyData function.
which is instead of the above it is
data: JSON.parse(extraFunctionProcess(fullData,details))
This has worked but due to the modification which I have done, it has brought up an error in my browser console which is
undefined inside the extraFunctionProcess.
I just shortened the code into I put online now.
I have actually found a solution to the problem. The modifyData function was the one with the problem. The return was inside another function.
Intead of the following
function modifyData(details){
for(var x=0 ;x<array.length;x++){
//this would do a massive loop which would
//return a json string that would be inside a function
}
}
function modifyData(details){
for(var x=0 ;x<array.length;x++){
return functionName(callback to be done);
//this would do a massive loop which would
//return a json string that would be
}
}
I have a scope that is not updated after assignment inside a factory http call.
var form = {}
var requestForm = {}
requestForm['name'] = $scope.brand.name;
requestForm['country'] = $scope.brand.countryCode;
So I'm setting a $scope.mergeId as my initializer as value 0, then the tableFactory.setMergeRequest will call a http call in the factory file and will return an object, with a boolean and an id #.
$scope.mergeId = 0;
//set merge request/id
tableFactory.setMergeRequest(requestForm).then(function(data){
if(data.mergeRequestStatus){
console.log(data);
$scope.mergeId = data.insertedRequestId; //456
}else{
console.log('no merge id');
}
});
form['mergeId'] = $scope.mergeId;
The boolean will be true, and it should assign the id (456) to the $scope.mergeId. Then that scope will be used to assign the form['mergeId'] variable that will be used in another http call.
When I check the console, the form variable is at zero so it's not updated. I took out the initializer but then it's saying is undefined. The http call is sending back data, it's just the scope is not being updated.
Has anyone gone through this issue before? Should I change the setup for this http call? I tried to this, but it's not setting the right value, it's setting an object.
form['mergeId'] = tableFactory.setMergeRequest(requestForm).then(function(data){
if(data.mergeRequestStatus){
return data.insertedRequestId
}else{
return null
}
});
the response I got from this way, is a d, how do i get the value?
Please help, I've been stuck with this issue for a while. Your help will be appreciated.
ADDITIONAL INFO
This is the http call where tableFactory.setMergeRequest is triggered.
var setMergeRequest = function(object){
var mergeRequestCall = {
method: 'POST',
url: CONFIG.PYTHON_API_END_POINT + '/api/mergerequest',
data: object
}
var d = $q.defer();
$http(mergeRequestCall)
.success(function(response){
d.resolve(response);
}).error(function(response){
d.resolve([]);
});
return d.promise;
}
The response is :
{
"insertedRequestId": 456,
"mergeRequestStatus": true
}
You should set the value where the promise is resolved, not set the value to the function
tableFactory.setMergeRequest(requestForm).then(function(data){
if(data.mergeRequestStatus){
form['mergeId'] = data.insertedRequestId;
}else{
form['mergeId'] = null;
}
});
I have an object (array type) ,its console representation looks like following image . please see the image
This array is created by restangulr using following code ,
restangularProvider.addResponseInterceptor(function (data, operation, what, url, response, deferred) {
if (operation == "getList") {
var extractedData;
extractedData = data.result;
extractedData.paginginfo = data.paginginfo;
return extractedData;
}
if (operation != "get") {
var item = { status: response.status };
feedBackFactory.showFeedBack(item);
}
return response.data;
});
How can I read the elements from this array, I want to extract properties like paginginfo ,also object collection
// The EDIT :1 js libraries I used here angularjsu 1.3.4, and restangular 1.4
My app.js : here I configured rest angular provider
restangularProvider.addResponseInterceptor(function(data, operation, what, url, response, deferred) {
if (operation == "getList") {
var extractedData;
extractedData = data.result;
extractedData.paginginfo = data.paginginfo;
return extractedData;
}
if (operation != "get") {
var item = {
status: response.status
};
feedBackFactory.showFeedBack(item);
}
return response.data;
});
// according to my knowledge this function will intercept every ajax call (api calls) and modify the response , unfortunately I need to apply custom modification because the getlist method must return collection but my api returning object, so according to restangular ,the above code is the possible solution, and here its fine its fetching the data.
userservice.js : this is angular service which using restangular
function(restangular) {
var resourceBase = restangular.all("account");
this.getUsers = function(pagenumber, recordsize) {
var resultArray = resourceBase.getList({
page: pagenumber,
size: recordsize
}).$object;
};
};
according to my knowledge .$object in restangulr resolve the promise and bring back the data, also I am getting the resultArray its looks like in the image in the console, here I can log this array so I think I got all the data from server and filled in this object. I applied some array accessing techniques available jquery and JavaScript like index base accessing , associate accessing but I am getting undefined ie.
resultArray[1] //undifiend;
In angular you can use angular.forEach(items, function(item){ //your code here});
Where items is the array you want to traverse.
If you want to access to one specific position use [], for example var item= items[5].
Then you can do item.property.
UPDATE
Your problem is that you are setting properties in an Array JS Object:
extractedData.paginginfo = data.paginginfo;
You should return the object data like it is and in your controller do something like:
var results= data.result;
var pagInfo= data.paginationInfo;
angular.forEach(results,function(result){});
It looks like the array is numerically indexed (0..1..5); you should be able to simply iterate through it using ForEach (in Angular) or .each (in Jquery).
Something like (JQuery):
$.each(array, function(key, value)
{
// key would be the numerical index; value is the key:value pair of the array index's element.
console.log(value.firstname); // should print the firstname of the first element.
});
First of all, as I said in the comments, you shouldn't be attaching named properties to arrays. Return an object thact contains what you need:
if (operation == "getList") {
return { values: data.result, paging: data.pagingInfo };
}
The getList() method returns a promise, so you need to use that:
this.getUsers = function(pagenumber, recordsize) {
resourceBase.getList({
page: pagenumber,
size: recordsize
}).then(function (data) {
console.log(data.values[0]);
console.log(data.paging.totalRecords);
});
};
So I'm trying to return the URL from a set of photos (using the getInterestingList) I am able to return them, but whenever I try narrow down the results and only return the source it just returns undefined in the console.
This is my code:
function getInteresting() {
var interestingStr = 'https://api.flickr.com/services/rest/?method=flickr.interestingness.getList&' + APIkey + '&per_page=20&format=json&nojsoncallback=1';
$.get(interestingStr, function (data) {
fetchLink(data);
});
}
function fetchLink(data) {
for (var i = 0; i < data.photos.photo.length; i++) {
//console.log(data.photos.photo[i].id);
var photoObject = data.photos.photo[i];
var getSizesStr = 'https://api.flickr.com/services/rest/?method=flickr.photos.getSizes&' + APIkey + '&photo_id=' + data.photos.photo[i].id + '&format=json&nojsoncallback=1';
$.get(getSizesStr, function (data) {
console.log(data.sizes.size.source); /**This is where i'm printing the result. Whenever I put in .source it returns undefined, but whenever I leave it as sizes.size it returns correctly**
});
}
What happens when I leave it as sizes.size:
[Object, Object, Object, Object, Object, Object, Object, Object, Object, Object]0: Objectheight: 75label: "Square"media: "photo"source: "https://farm4.staticflickr.com/3900/15073487900_0b89b0e136_s.jpg"url: "https://www.flickr.com/photos/janleonardo/15073487900/sizes/sq/"width: 75
when I try get the source: (desired result:
undefined
Any Ideas? Thanks
edit: I'm using REst / JSON
Fixed:
What I did was add another for loop inside my GET call to the getSizes api,
$.get(getSizesStr, function (data) {
for (var x = 0; x < data.sizes.size.length; x++) {
console.log(data.sizes.size[x].source);
and it worked.
I am running into a strange problem with not being able to update properties on an object that is returned as part of a deferred promise.
// Update or Insert status information into the idr_status table
this.updateStatus = function (idrInspData, statusId, submitting)
{
var def = new $.Deferred();
self.getIdrStatus (idrInspData.idr_date).done (function (idrStatus)
{
//status record exists for the day update record
idrStatus.status_msg_id = statusId;
idrStatus.submitted = submitting ? 1 : 0;
idrStatus.modified = 1;
idrStatus.action_needed = statusId.search('+') != -1 ? true : false;
// update the status
self.db.updateRecord (self.idrStatusTableName, idrStatus).always (
function (updateResult)
{
def.resolve(true);
});
}).fail (function (result)
{
def.reject(result);
});
return (def.promise ());
}
The idrStatus object is returned from a SQLite resultset and then converted to a plain JS object then resolved to the done function above. The object comes in but any attempt to edit the properties are simply ignored and the same object is passed Unchanged to the updateRecord function. I am puzzled? Why would the object be locked?