Reputation: 13216
I keep getting the following error: TypeError: Cannot read property 'then' of undefined, in checkInventoryData. How can I resolve it?
function checkInventoryData(url, size, code) {
var inventoryData = { };
return $http.get(url).then(function(response) {
var html = response.data;
// getting error here: TypeError: Cannot read property 'then' of undefined
getInventoryProductQty(html, size).then(function(result) {
result = inventoryData.productQty;
});
return inventoryData;
});
}
function getInventoryProductQty(html, size) {
var inventoryAvailable;
var deferred = $q.defer();
try {
var inventoryAvailablity = getInventoryAvailability(html, size);
inventoryAvailablity.then(function(result) {
if(result) {
inventoryAvailable = result.getAttribute('data-available');
deferred.resolve(inventoryAvailable);
return deferred.promise;
}
});
}
catch(err) {
inventoryAvailable = null;
return inventoryAvailable;
}
}
Upvotes: 0
Views: 1046
Reputation: 2314
What you're doing for now, inside getInventoryProductQty
inventoryAvailablity.then(function(result) {
if(result) {
inventoryAvailable = result.getAttribute('data-available');
deferred.resolve(inventoryAvailable);
return deferred.promise;
}
});
This is not a return statement and so your function does not return anything.
If what you would like to return is inventoryAvailable
(once it has been retrieved), you would do something like
return inventoryAvailablity.then(function(result) {
if(result) {
inventoryAvailable = result.getAttribute('data-available');
return inventoryAvailable;
} else {
/* reject ? */
}
});
[edit]
I would actually rewrite the function this way
function getInventoryProductQty(html, size) {
var inventoryAvailable;
try {
var inventoryAvailablity = getInventoryAvailability(html, size);
return inventoryAvailablity.then(function(result) {
if(result) {
inventoryAvailable = result.getAttribute('data-available');
return inventoryAvailable;
} else {
/* reject ? */
}
});
}
catch(err) {
return $q.reject(err);
}
}
Upvotes: 1
Reputation: 351403
Once you rely on a promise, you need to make sure to keep returning promises in the call chain.
Here is the suggested code:
function checkInventoryData(url, size, code) {
// Warning: code is nowhere used!
// Return(!) the promise:
return $http.get(url).then(function(response) {
var html = response.data;
return getInventoryProductQty(html, size);
});
}
function getInventoryProductQty(html, size) {
try {
// return the result of `then`, which is a promise:
return getInventoryAvailability(html, size).then(function(result) {
if(result) {
// Just return the value. No need to return a promise.
// I assume you have a productQty property here:
return result.getAttribute('data-available').productQty;
} else { // also deal with the failure:
throw "no result from getInventoryAvailability";
}
});
}
catch(err) {
// return a failed promise here:
return $q.reject(err);
}
}
Don't expect checkInventoryData
to synchronously return the value. It is also a promise, and you need to apply then
to it to get the promised value in a callback function. Also make sure to use a catch
method whenever you call checkInventoryData
, so you can deal with errors.
Upvotes: 1
Reputation: 10672
You need to return a promise from getInventoryProductQty
, right now you return null in the error case, but nothing in the normal case (and neither of those are promises.
EDIT - showing this answer in OPs code, and comment on the structure.
function checkInventoryData(url, size, code) {
var inventoryData = { };
return $http.get(url).then(function(response) {
var html = response.data;
// getting error here: TypeError: Cannot read property 'then' of undefined
getInventoryProductQty(html, size).then(function(result) {
result = inventoryData.productQty; // this has not been set at this point, you need to set it somehow (@trincot's comment)
});
return inventoryData;
});
}
function getInventoryProductQty(html, size) {
var inventoryAvailable;
var deferred = $q.defer();
try {
var inventoryAvailablity = getInventoryAvailability(html, size);
return inventoryAvailablity.then(function(result) { // need to add this return to return the result of the then func
if(result) {
inventoryAvailable = result.getAttribute('data-available');
deferred.resolve(inventoryAvailable);
return deferred.promise;
}
});
}
catch(err) {
//inventoryAvailable = null;
//return inventoryAvailable;
return $q.resolve(null); // need something like this to return a promise from the failure case
}
}
You also should make getInventoryAvailability
return a promise so that it can be called with a .catch
instead of a try...catch
, but that's beyond the scope of this
Upvotes: 1