I am getting the reject is undefined error in my angular controller and I can not figure out why. This is the method. I added all libraries that are required.
Thank you in advance if you need more information let me know
function getUsers() {
return $http.get('../Admin/GetUsers/').then(function (response) {
return response.data;
}, function failureCallback(response) {
reject("Error!");
});
}
There is no reject defined in your code, so naturally trying to use it as a function will fail with a ReferenceError.
The promise returned by $http.get has already been rejected by the time your second handler has been called. Consequently, you probably don't want to handle rejections at all:
function getUsers() {
return $http.get('../Admin/GetUsers/').then(function (response) {
return response.data;
});
}
If you want to handle the rejection but still have the promise from getUsers rejected, you need to either throw in your handler or return a promise that is or will be rejected:
function getUsers() {
return $http.get('../Admin/GetUsers/').then(function (response) {
return response.data;
}, function failureCallback(err) { // Note it's an error, not a response
// Do something here, then
throw err;
});
}
If you are handling the failure and converting it into a success, you'd do that by returning a value to use (or a promise that will ultimately resolve with the value to use) instead of the value from get:
function getUsers() {
return $http.get('../Admin/GetUsers/').then(function (response) {
return response.data;
}, function failureCallback(err) { // Note it's an error, not a response
// Do something here, then
return valueToUseInstead;
});
}
...but I don't think that's what you're trying to do.
You can do it in two ways.Either entire method in controller or use service to return rejected value that you want.
function getUsers() {
var res=$http.get('../Admin/GetUsers/');
res.success(function (response) {
return response.data;
});
res.error(function(){
alert("failure");
});
}
Or
Controller.js:
function getUsers() {
userService.getAll().then(function (response) {
return response.data;
}, function(response) {
alert(response);
});
}
Service.js
this.getAll = function() {
var d = $q.defer();
res.success(function (data) {
d.resolve(data);
});
res.error(function(data){
d.reject(data);
});
}
Insert '$q' in service.
I've seen plunker. I don't understand what you searching for.
This is error free plunker.
Plunker
Thank you.
Related
In my angularjs app I have the following code on button click:
if (!$scope.isChecked) {
$scope.getExistingName($scope.userName).then(function (data) {
$scope.userName = data;
});
}
//some processing code here then another promise
myService.save($scope.userName,otherparams).then(function (res) {
//route to page
}, function (err) {
});
The issue here is if $scope.isChecked is false, it goes inside the promise and since it takes time to resolve it comes out and goes to next line of code. Because of this $scope.userName is not updated and uses old values instead of the updated value returned.
Whats the best way to handle this?
You can use $q. First you have to inject $q in your angular controller.
//Create empty promise
var promise;
if (!$scope.isChecked) {
promise = $scope.getExistingName($scope.userName).then(function (data) {
$scope.userName = data;
});
}
// Wait or not for your promise result, depending if promise is undefined or not.
$q.all([promise]).then(function () {
//some processing code here then another promise
myService.save($scope.userName,otherparams).then(function (res) {
//route to page
}, function (err) {
});
});
If the myService.save need to wait for the $scope.getExistingName promise just compute that operation inside the "then" statement.
if (!$scope.isChecked) {
$scope.getExistingName($scope.userName).then(function (data) {
$scope.userName = data;
myService.save($scope.userName,otherparams).then(function (res) {
//route to page
}, function (err) {
});
});
}
//some processing code here then another promise
I've recently started to upgrade from Bootstrap 3 to Bootstrap 4, and that requires I also upgrade from AngularJS 1.5.8 to a minimum of AngularJS 1.6.1. I have a simple AngularJS/MVC application with the following code setup:
/scripts/app.js (contains routing)
/scripts/controllers.js (contains controllers, method calls, etc)
/scripts/services.js (contains the callback methods that hit the C# controllers and bring back data, or "do things" (CRUD methods)
In my controllers.js, I have a method:
function init() {
api.initialIndexLoad(
function(result) {
if (result.error) {
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
} else {
vm.dataList = result.theDataFromCSharp;
}
vm.loaded = true;
}
);
}
init();
This makes a call to my services.js, where I have this code:
"use strict";
angular
.module("CustList.services", ["ngResource"])
.service("api",
function api($resource, $http, notificationService) {
function handleError(err, fn) {
if (!fn) {
notificationService.error(err);
} else {
fn(err);
}
}
return {
initialIndexLoad: function(callback, error) {
$http.get("/Customers/InitialIndexLoad")
.success(callback)
.error(function(e) {
handleError(e, error);
});
}
};
}
);
So, of course, after updating my libraries to AngularJS 1.6.1 (Actually, I went straight to AngularJS 1.7.5), I started to get errors, and after a while figured out that the promise syntax had changed. So I tried to change with it, and updated my services.js to be:
"use strict";
angular
.module("CustList.services", ["ngResource"])
.service("api",
function api($resource, $http, notificationService) {
function handleSuccess(response) {
return response.data;
}
function handleError(err, fn) {
if (!fn) {
notificationService.error(err);
} else {
fn(err);
}
}
return {
initialIndexLoad: function() {
$http
.get("/Customers/InitialIndexLoad")
.then(handleSuccess)
.catch(handleError);
}
};
}
);
The errors went away, and I thought I had this upgrade licked, until I realized: I wasn't actually getting the data back! That new handleSuccess method I'd created was getting the data in the response, but the return response.data wasn't returning the data back to my controllers.js method, so I could plug it into vm.dataList.
It doesn't throw an error - it just does nothing. I'd appreciate help figuring this out!
The service method needs to return the $http promise.
app.service("api",
function api($http, notificationService) {
function handleSuccess(response) {
return response.data;
}
function handleError(err) {
notificationService.error(err);
throw err;
}
return {
initialIndexLoad: function() {
̶$̶h̶t̶t̶p̶
return $http
.get("/Customers/InitialIndexLoad")
.then(handleSuccess)
.catch(handleError);
}
};
}
);
Notice that the errorHandler needs to re-throw the error. Otherwise the handler will convert the rejected promise to a fulfilled promise.
The controller needs to use the .then and .catch methods:
function init() {
var promise = api.initialIndexLoad();
promise.then(function(result) {
if (result.error) {
notificationService.danger("<h5>An error occurred.</h5><h6>Details: {0}</h6>".format(result.error));
} else {
vm.dataList = result.theDataFromCSharp;
}
vm.loaded = true;
}).catch(functions(err) {
console.log(err);
throw err;
});
}
The .then method returns a new promise which is resolved or rejected via the return value of the successCallback, errorCallback (unless that value is a promise, in which case it is resolved with the value which is resolved in that promise using promise chaining.
For more information, see
AngularJS $q Service API Reference - The Promise API
You're Missing the Point of Promises
Return inside of initialIndexLoad
so
return $http
.get("/Customers/InitialIndexLoad")
.then(handleSuccess)
.catch(handleError);
Would guess this is it, maybe lost during refactor/upgrade.
I am trying to delete a post from a list. The delete function is performing by passing serially to a delete function showed below.
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref)
.success(function (data) { });
}
After performing the function, I need to reload the http.get request which used for listing the list.
$http.get("api/phone_accept.php")
.then(function (response) { });
Once the function performed. The entire list will reload with new updated list. Is there any way to do this thing.
Try this
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref)
.success(function (data) {
//on success of first function it will call
$http.get("api/phone_accept.php")
.then(function (response) {
});
});
}
function list_data() {
$http.get("api/phone_accept.php")
.then(function (response) {
console.log('listing');
});
}
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref)
.success(function (data) {
// call function to do listing
list_data();
});
}
Like what #sudheesh Singanamalla says by calling the same http.get request again inside function resolved my problem.
$scope.go = function(ref) {
$http.get("api/phone_recev.php?id="+ref).success(function (data) {
//same function goes here will solve the problem.
});}
});
You can use $q - A service that helps you run functions asynchronously, and use their return values (or exceptions) when they are done processing.
https://docs.angularjs.org/api/ng/service/$q
Inside some service.
app.factory('SomeService', function ($http, $q) {
return {
getData : function() {
// the $http API is based on the deferred/promise APIs exposed by the $q service
// so it returns a promise for us by default
return $http.get("api/phone_recev.php?id="+ref)
.then(function(response) {
if (typeof response.data === 'object') {
return response.data;
} else {
// invalid response
return $q.reject(response.data);
}
}, function(response) {
// something went wrong
return $q.reject(response.data);
});
}
};
});
function somewhere in controller
var makePromiseWithData = function() {
// This service's function returns a promise, but we'll deal with that shortly
SomeService.getData()
// then() called when gets back
.then(function(data) {
// promise fulfilled
// something
}, function(error) {
// promise rejected, could log the error with: console.log('error', error);
//some code
});
};
I'm trying to submit a form that require that the user email is not duplicated, but I want to make an small animation before the POST request. In the $scope.process function I'm getting:
TypeError: Cannot read property 'catch' of undefined.
That's happening because $scope.process is returning before the $http.post is complete, but how can I make process() return the promise instead of undefined?
So, this is what I have so far:
//The submit form function
$scope.submitForm = function () {
$('.btn').attr('disable');
if ($scope.form.$valid) {
$scope.process($scope.account)
.catch(function (err) {
if (err.code === 'duplicate') {
// handle error
}
});
return false;
}
};
//This is the one in charge to send the request
$scope.process = function(body) {
// Timeout before http post to wait for animation
$timeout(function() {
return $http.post(postUrl, body).then(function (response) {
// This return a promise if I remove the $timeout
var nextPage = response.data;
}).catch(function (err) {
throw err;
});
}, 300);
// Return undefined due to $timeout
};
Thanks in advance.
You were getting TypeError: Cannot read property 'catch' of undefined, because you weren't returning promise from process function at all.
Do return $timeout promise from process function & apply .then & .catch over $timeout promise object.
By returning $timeout service the inner $http.post will return a data, so that will make proper chaining mechanism.
Code
$scope.process = function(body) {
// returned promise from here
return $timeout(function() {
//returned $http promise from here.
return $http.post(postUrl, body).then(function (response) {
// This return a promise if I remove the $timeout
nextPage = response.data;
return nextPage; //return data from here will return data from promise.
}).catch(function (err) {
throw err;
});
}, 300);
};
I am developing a file reading service that look like this:
angular.factory('fileService', fileService);
function fileService($cordovaFile){
var service = {
readFile: readFile
};
return service;
///////////////
function readFile(path, file){
$cordovaFile.readAsText(path, file)
.then(function (success) {
console.log("read file success");
console.log(success);
return success;
}, function (error) {
alert("Fail to read file:"+error);
console.log("Fail to read file");
console.log(error);
return false;
});
}
}
And then using it like this:
var data = fileService.readFile(cordova.file.dataDirectory,filename);
console.log(data) //return undefined
The problem is it fail to return the data. How can I get the data return back?
Your problem is that you are not actually returning any result from the readFile function. You are returning data from your callback functions but if you come to think of it...that result is returned to the function readFile itself and it stays inside that function. What you would want to do is return the whole result of the function readFile and then resolve the promise in the controller where you use it. Here is the code:
angular.factory('fileService', fileService);
function fileService($cordovaFile){
var service = {
readFile: readFile
};
return service;
function readFile(path, file){
return $cordovaFile.readAsText(path, file);
}
}
And then you use it like this:
var data = fileService.readFile(cordova.file.dataDirectory,filename);
data.then(function (success) {
// Do whatever you need to do with the result
}, function (error) {
/// Handle errors
});
In general, when you use services to implement some kind of functionality that uses promises and returns result, you should always return the promise object which can be than resolved anywhere that it is needed.
I highly recommend that you read this great explanation for promise objects.
Your function readFile returns nothing, so, firstly you should be returning the promise:
function readFile(path, file) {
return
$cordovaFile.readAsText(path, file).then(function (success) {
console.log('Read file success');
console.log(success);
return success;
}, function (error) {
alert('Fail to read file: ' + error);
console.log('Fail to read file');
console.log(error);
return false;
});
}
And then, if you try to use it the way you were, you'll not get undefined anymore, you'll get a promise.
But since it's an async method, you'll get that promise still pending, and you probably don't want that, since you'll need the promise's fulfilled value. So, you should use it like this:
fileService.readFile(cordova.file.dataDirectory, filename).then(function(data) {
// use data here
});