(intermediate value).error is not a function - AngularJs - angularjs

I'm calling a method inside WebApi 2 controller everything is working as expected however when I check the developer console I see the following error message:
Error: (intermediate value).error is not a function
Now I've done the research and some people have said: You're missing a closing semi colon within your method, however I've gone through my code and I can't see anywhere that I'm missing this.
My Angular Js login function:
$scope.Login = function () {
var emailAddress = $scope.emailAddress.trim();
var password = $scope.password.trim();
var valid = loginApi(emailAddress, password);
};
Which calls this function:
function loginApi(emailAddress, password) {
var login = { "EmailAddress": emailAddress, "Password": password };
$http.post("/api/Login/", login).success(function (data, status) {
alert('success');
}
.error(function (error, status) {
alert(error);
}));
};

I may be wrong but don't you need a closing parenthesis after your .success function and then remove one at the end of the .error?
$http.post().success(function() {}).error(function() {});
Otherwise it would seem like you're enclosing your error in your success.
The other thing to think about is that in Angular both .success and .error have been deprecated and they suggest using then:
Angular API: $http
The $http legacy promise methods success and error have been deprecated. Use the standard then method instead.

Related

PUT and POST Angularjs

I have an Ionic project with a WCF RESTful service, I want to be able to Insert and Update data. I can already view data with GET method but can't find anything on the internet for PUT and POST. How would I be able to accomplish this?
GET Method
$scope.selectedDist= function() {
$http.get("http://192.168.1.113/Service1.svc/GetAllComp")
.success(function(data) {
var obj = data;
var ar = [];
angular.forEach(obj, function(index, element) {
angular.forEach(index, function(indexN, elementN) {
ar.push({CompID: indexN.CompID, CompName: indexN.CompName});
$scope.districts = ar;
});
});
})
.error(function(data) {
console.log("failure");})
};
Post methods I tried
#1
$scope.insertdata = function() {
var ar = [{'M1':$scope.M1, 'M2':$scope.M2,'M3':$scope.M3,'M4':$scope.M4,'M5':$scope.M5,'M6':$scope.M6,'M7':$scope.M7,'M8':$scope.M8,'M9':$scope.M9,'M10':$scope.M10,}]
$http.post("http://192.168.1.113/Service1.svc/GetAllComp", ar)
.success(function(data)
{
console.log("data inserted successfully")
})
.error(function(data)
{
console.log("Error")
})
#2
$scope.insertdata = function() {
var ar = [{'M1':$scope.M1, 'M2':$scope.M2,'M3':$scope.M3,'M4':$scope.M4,'M5':$scope.M5,'M6':$scope.M6,'M7':$scope.M7,'M8':$scope.M8,'M9':$scope.M9,'M10':$scope.M10,}]
$http ({
url : "localhost:15021/Service1.svc/TruckDetails" ,
Method : "POST" ,
headers : {
'Content-Type' : 'Application / json; charset = utf-8'
},
Data : ar
})
Also Would I need to make a POST or PUT method on my Service as well or can I use the GET methods?
You can use a get method, in combination with a querystring to post and put data but that is not what it was designed for and should be avoided for several reasons such as security.
That being said, it is not that difficult to use post and put in angular and in the following , rather naive service , you can see all that is required to do is passing your data in the service function you're invoking.
.service('MyService', function($http) {
this.postMethod = function(data) {
return $http.post('http://my.url', data);
};
this.putMethod = function(id, data) {
return $http.put('http://my.url/' + id, data);
};
}
So that in your controller you can inject and invoke the service methods with the $scope data that needs to be stored.
After taking a look at your attempts you seem to be using the same url for both get and post: "http://192.168.1.113/Service1.svc/GetAllComp" which actually leads me to believe you haven't thought about implementing these methods on your server. Can you confirm this?
Apart from that, it is always usefull to look at statuscodes when trying to send requests because they provide a great deal of information about the nature of the error that occurs. You can investigate that in either your console or an external program such as Fiddler.
P.S.
Deprecation Notice The $http legacy promise methods success and error
have been deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.

Angular test using $httpBackend fails with "400 thrown" error

For hours I've been trying to test my NewPostController with $httpBackend. The problem is whenever I set non-2xx status code in the response, the test fails.
NewPostController has the following method:
$scope.submit = function () {
var newPost = $scope.newPost;
PostService.insertPost(newPost).then(function (post) {
$location.path("/my-posts");
}, function (status) {
$scope.form.$setPristine();
$scope.error = status;
});
};
I have a problem testing the failure path:
it(...) {
...
$scope.post.text = "";
$httpBackend.expectPOST("/create-post", {"post":$scope.post}).respond(400);
$scope.submit();
$httpBackend.flush();
expect($scope.error).toBeDefined();
$scope.post.text = "This is a valid text.";
$httpBackend.expectPOST("/create-post", {"post": $scope.post}).respond(200);
$scope.submit();
$httpBackend.flush();
expect($location.path()).toBe("/my-posts");
});
The test fails with a message "400 thrown" (no callstack). I tried to change the order of subtests, use whenPOST instead of expectPOST and combine the methods as they do in Angular docs (https://docs.angularjs.org/api/ngMock/service/$httpBackend) but without success.
Please help.
EDIT:
Now when I look at PostService, it makes sense where the "400 thrown" comes from but I expected the error to be handled by angular. I threw it because of the section "Handling problems in nested service calls" of this article. It is supposed to be a shorter version of deferred.resolve/reject mechanism.
this.insertPost = function (newPost) {
return $http({
method: "post",
url: "/create-post",
data: {
post: newPost
}
}).then(function (res) {
return (res.data);
}, function (res) {
throw res.status;
});
};
This is indeed strange, and is perhaps something the angular team didn't consider.
When a promise is rejected by throwing (as you're doing), the angular $exceptionHandler service is called with the thrown exception. By default, this service just logs the exception in the browser console.
But when using ngMocks, this service is replaced by a mock implementation that can either log or rethrow the exception. The default mode is to rethrow, in order to make a test fail when an exception is thrown.
My advice would be to avoid using throw to simply reject a promise, and thus replace
function (res) {
throw res.status;
}
by
function (res) {
return $q.reject(res.status);
}
But if you really want to keep using throw, you can also configure the mock exceptionHandler to log instead of rethrowing:
beforeEach(module(function($exceptionHandlerProvider) {
$exceptionHandlerProvider.mode('log');
}));

AngularJS ngResource $save feedback

Hello I am using ngResource $save method and I get two different behaviours, I don't understand why
First I'm using it in this way:
$scope.user = new User($scope.user);
$scope.user.$save(function () {
$window.location.href = //redirection here;
}, function (response) {
$scope.form.addErrors(response.data.errors);
});
Then I have another controller when I'm doing a similar operation, but even getting 404 or 422 errors from the server the first callback is executed and the errors callback is ignored.
Does anyone have any idea of this? I've been searching in Google for hours trying to find more documentation about $save but I'm still stuck with this problem.
Thank you.
Well, the problem was on an interceptor I am using to detect 401 (unauthorized errors)
here is the interceptor, notice that you must return $q.reject(response) otherwise the other callbacks are not called (in my case the error callback in ngResource.$save)
MyApp.config(function ($httpProvider) {
$httpProvider.interceptors.push(function($window, $q) {
return {
'responseError': function(response) {
if (response.status == 401) { // Unathorized
$window.location.href = 'index.html';
}
// return response; <-- I was doing this before cancelling all errors
return $q.reject(response);
}
};
});
});

Hitting a REST-based Service With AngularJS Resource

I have an AngularJS app. In this app, I'm trying to ping a REST API. This API returns a list of orders.
I need to be able to handle the scenario where I successfully GET the orders. I also need to handle the
scenario where the request to GET the orders fails. In an attempt to do this, I'm using the ngResource
module. My controller looks like the following:
myController.js
myApp.controller('myController',
function myController($scope, myService) {
myService.getOrders(function(data) {
$scope.orders = data;
});
}
);
The definition of myService is stored in myService.js. That file looks like this:
app.factory("myyService", function($resource, $log) {
return {
getOrders: function(onSuccess) {
var orders = $resource("http://localhost:1000/orders", { fetch:{method:'JSON'} });
orders.fetch(function (response) {
console.log(response);
onSuccess(response.data);
});
}
};
});
When I run this code, I get a runtime error. The error says:
TypeError: Object function g(b){z(b||{},this)} has no method 'fetch'
Maybe there has to be something I don't understand. In my mind, I see fetch defined.
The other question I have is how do I set this up to handle failed requests? Like a 404 or 502?
You forgot the curly braces after the URL parameter...
Change: http://localhost:1000/orders", { fetch :
To: http://localhost:1000/orders", {}, { fetch :
app.factory("myyService", function($resource, $log) {
return {
getOrders: function(onSuccess) {
var orders = $resource("http://localhost:1000/orders", {}, { fetch : {method:'JSON'} });
orders.fetch(function (response) {
console.log(response);
onSuccess(response.data);
});
}
};
});
[EDIT]
To handle errors from the server side, you need to set the second function in the resource call.
Example :
orders.fetch(function success() {...},
function error() {... this will execute in a http error, 400 or 500}
);

Exception handling with jsonp requests in angularjs

I have the following code which make seperate requests for jsonp data.
In the code "doRequestA" works fine and returns a result. The issue I have is
I need to catch any errors if they occur. I have tried implementing this in
"doRequestB", but only receive the alert error (I have ommitted the callback from doRequestB).
Here is the fiddle http://jsfiddle.net/a4Rc2/417/
function jsonp_callback(data) {
alert(data.found);
}
function jsonp_example($scope, $http) {
$scope.doRequestA = function () {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=jsonp_callback";
$http.jsonp(url);
};
$scope.doRequestB = function () {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts";
$http.jsonp(url)
.success(function (data) {
alert(data.found);
}).error(function (data, status, headers, config) {
alert('error');
});
};
}
Any advice is greatly appreciated, thanks in advance.
You actually are using $http.jsonp incorrectly in both cases. You just can't see the error in the first case because you are not handling it.
With Angular.js's $http.jsonp method, the callback method is handled automatically. You shouldn't use your own methods in the result string, but rather insert JSON_CALLBACK (exactly as written) into your string. This way, you can handle the response using the promise returned from Angular. If you watch the network activity (say, using Firebug or the developer tools in your browser of choice), you'll see JSON_CALLBACK replaced with something like angular.callbacks._0*.
In the second example, you don't have a callback method defined at all, so the result will always error. There's actually no way for the jsonp result to be handled, since it simply returns the JSON object without a callback method, and the result just is ignored.
Here's a working result: http://jsfiddle.net/tPLaN/1/
The code:
function jsonp_callback(data) {
alert(data.found);
}
function jsonp_example($scope, $http) {
$scope.doRequestA = function() {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";
$http.jsonp(url).success(function(data) {
jsonp_callback(data);
});
};
$scope.doRequestB = function() {
var url = "http://public-api.wordpress.com/rest/v1/sites/wtmpeachtest.wordpress.com/posts?callback=JSON_CALLBACK";
$http.jsonp(url)
.success(function (data) {
alert(data.found);
}).error(function (data, status, headers, config) {
alert('error');
});
};
}
The only thing I changed was
Correcting the two URLs.
Moving the callback handler on the first method inside the .success() method on the promise.
Believe it or not, the need for JSON_CALLBACK is in the documentation for $http.jsonp, but it's sort of hidden.
* Note, please do not use the replacement for JSON_CALLBACK for anything. It's a private method generated by Angular, I am just showing it to help make more sense of what is happening.

Resources