Migrating from http to ngResource Angular - javascript

It's been 3months since I've used angular and I'm loving it. Finished an app using it and now I'm on a code refactoring or improving my code for better practice. I have an Api service.js that used $http and I want to migrate it to using $resource :)
I have here a sample of my api code using $http:
Service.js
authenticatePlayer: function(postData) {
return $http({
method : 'POST',
url : api + 'auth/player',
data : postData,
headers : {'Content-Type' : 'application/json'}
});
},
#Controller.js
Api.authenticatePlayer(postData).then(function (result){
//success
}, function(result) {
//error also this will catch error 400, 401, and 500
});
The above code are working and now here is my first attempt on using $resource:
authenticate: function() {
return $resource(api + "auth/:usertype",
{
typeOfUser : "#usertype" //types can be player, anonymous, admin
},
{
post : { method : "POST" }
}
);
}
#Controller
var postData = {
email : scope.main.email,
password : scope.main.password
};
var loginUser = new Api(postData);
loginUser.$post(); //error T__T
That just how far I get, don't know how to pass a data to my api using $resource from my controller. That just one part of my api call, there's still a bunch of it but for now this will do. :D.
Any help is greatly appreciated.
Thanks

You could try this:
API
authenticate: function(){
return $resource(api+"auth/:usertype",{},post:{method:"POST"});
}
Note: :usertype in URL means that the value of usertype property which you passed into postData will replace the part of URL
Controller
var postData = {email:scope.main.email,password:scope.main.password};
API.authenticate().post({usertype:'player'},postData,function(response){
console.log(response);
});
Or you could fetch response like this:
var response = API.authenticate().post({usertype:'player'},postData);
Hope this is helpful.

Related

Calling RESTful apis through ajax and angular js

If the URL that is to be hit has to be passed variables i.e.
API.openweathermap.org/data/2.5/forecast/city?name=[random_city_name]&APPID=[key_value],
then what is better to use ajax or angular js.
If I am using ajax then how am I supposed to pass the variable? I am a newbie in this. So, need your help.
Your url seems to have request parameters and assuming you are using angular1
For this, you can use
$http({
method: 'GET',
url: url,
headers: {},
params : {}
})
Put your parameters as a map and $http will take care of creating an url.
Refer $http documentation here
what is better to use ajax or angular js
You can't compare as AJAX provides a way to communicate (send requests and get responses) with the server asynchronously and AngularJS used AJAX to extends the 2-way data binding.
To accomplish the above situation we can use Angular $http service.
var baseUrl = API.openweathermap.org/data/2.5/forecast/city;
var method = 'GET';
var data = {};
var params = {
"name":cityName,
"APPID":key_value
};
$http({
method: method,
url: baseUrl,
params : params,
data : data
}).then(function mySucces(response) {
$scope.data = response.data;
}, function myError(response) {
$scope.data = response.statusText;
});
You can use angular $http service and pass your params like below.
var UserInfo = function() {
$scope.userID = "1111";
var req ={
"method":"GET",
"url": someURL + $scope.userID,
"withCredentials":true
};
$http(req).then(function(response) {
alert('success');
}, function(response) {
alert('error');
});
};

$http.post is not a function

I am trying to submit a form data to an API endpoint which I created. I have tested it in PostMan and the API functions well and I can get the data in successfully. But while connecting that API endpoint to a function in angular js I get the following error.
Heres my code:
$scope.saveSession = function() {
$http.post("/session/survey", $scope.session).success(function(data, status) {
$window.location.href = '/';
console.log("Sucessfully getting data" + JSON.stringify(data));
})
}
Note:
$scope.session is an object that being populated by using the ng-model tag.
For example:
<input type="text" ng-model="session.title">
Edit (Controller Code):
// This is our controller for the bio page
var session = angular.module('session', ['sessionService'])
session.controller('sessionCtrl', function($scope, $http, $window, sessionServices) {
$scope.session = {};
$scope.saveSession = function() {
$scope.session.sessionNo = 1;
$scope.session.coach = "mmmm";
$scope.session.modules = "wokr place";
//console.log(user);
$http.post("/session/survey", $scope.session).success(function(data, status) {
$window.location.href = '/';
console.log("Sucessfully getting added bio" + JSON.stringify(data));
})
};
});
That's because .success() really isn't a function. As the documentation explains, a promise is returned by $http.post() which you can chain with .then()
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
Use promises, "success" function doesn't exists in $http object($http success and error methods are available only in older versions of Angular 1.x, but they've removed in Angular 1.6):
// Simple GET request example:
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
More in official documentation https://docs.angularjs.org/api/ng/service/$http
It's because you're using $http.post().success.
Try;
$scope.saveSession = function() {
$http.post("/session/survey", $scope.session).then(function(data, status) {
$window.location.href = '/';
console.log("Sucessfully getting data" + JSON.stringify(data));
})
}
We use .then to return a "promise" from the $http service.
Hope it helps!
I just dealt with a similar issue with versions 1.7.2 and 1.7.4. It's not exactly the same issue because I was never using .success but I'm posting here because this post comes up first when searching.
When using the shortcut version $http.post(/api/endpoint/', data) I would get:
"TypeError: $http.post is not a function"
And if I used it with the callbacks exactly as it appears in the documentation:
$http({method: 'POST', url: '/api/endpoint/', data: $scope.newObject}).then(function (response) {
$scope.status = response.status;
$scope.data = response.data;
}, function (response) {
$scope.data = response.data || 'Request failed';
$scope.status = response.status;
});
I was getting
"TypeError: $http(...).then is not a function"
In this case the problem was that I had both $resource and $http in the same controller. Not sure if this is the intended behavior but removing $resource suddenly made $http work again.
Hopefully this helps someone else

How can I use"$timeout" in factory using AngularJS?

I have the services and within particular time duration if response is come than ok, other wise show error in popup.
Here is my service code:
angular.module('server', [])
.factory('api', function($http) {
var server = "http://myapi-nethealth.azurewebsites.net";
return {
//Login
login : function(formdata) {
return $http({
method: 'POST',
url: server + '/Users/Login',
data: $.param(formdata),
headers: { 'Content-Type' : 'application/x-www-form-urlencoded'},
})
},
};
});
Please tell me how can I use timeout property in services.
Read this post - How to set a global http timeout in AngularJs
Where you can set a timeout for your http calls.
You can inject the above factory in your controller and then make a call with success and error callbacks like below
api.login(formdata)
.success(function(){ alert("success"); })
.error(function(){ alert("error"); });

Is there a method in angularJS thats equal to getJSON. [Newbie alert]

I'm newbie at javascript, angularJS and JQuery, but I have just started programming a angularJS app where i use JQuery to get a JSON from a webserver like this:
var obj = $.getJSON( "http://something.com/lol?query="+ $scope.searchString, function() {
$scope.items = obj.responseJSON.entries;
}
Is there a method equal to $.getJSON in angularJS? So that I don't have to import the JQuery library.
Thanks in advance, newbie.
This is my solution so far:
function InstantSearchController($scope, $http){
$scope.search = function() {
$http.jsonp("http://something.com/lol?query="+ $scope.searchString + "?json_callback=JSON_CALLBACK").success(
function(data, status) {
console.log(data);
}
);
}
but I'm getting the error msg:
Uncaught SyntaxError: Unexpected token :
why is this? what am I doing wrong?
}
Because of the help i got from people answering my question I finally managed to fix it, and i did it like this:
app.controller('myController', function($scope, $http){
$scope.items = [];
$scope.search = function() {
$http({method: 'JSONP', url: "http://something.com/lol?callback=JSON_CALLBACK&query="+ $scope.searchString}).
success(function(data, status) {
$scope.items = data.entries;
}).
error(function(data, status) {
console.log(data || "Request failed");
});
};
Hope this helps anyone who has the same problem in the future :D
You could use $http to send AJAX requests in Angular.
You may use JSONP requests with $http.jsonp
https://docs.angularjs.org/api/ng/service/$http#jsonp
function ListProdcutsCtrl($scope, $http) {
var request = {'searchString' : 'apple'};
$http.get('/api/products', request).success(function(response) {
$scope.products_table_data = response.products;
});
There is an alternative in AngularJS called $http, you can find more here.
For instance :
$http({method: 'JSONP', url: 'http://domain.com/page?json_callback=JSON_CALLBACK'}).success(
function(data, status) {
// your stuff.
}
);
Or even shorter :
$http.jsonp('http://domain.com/page?json_callback=JSON_CALLBACK').success(
function(data, status) {
// your stuff.
}
);
JSONP (JSON Padding) allows you to get JSON data from another domain. However, the data you get should not be plain JSON, but rather a Javascript file like this :
JSON_CALLBACK([
{"name": "apple", "color": "red"},
{"name": "banana", "color": "yellow"}
]);
If your JSON data you need comes from the same domain, you do not need JSONP.
JSONP is used to overcome the cross-domain restriction of the AJAX URL calls.
With AngularJS (v1.5), you can use this code to send cross domain requests:
$http.jsonp(baseurl+'?token=assume_jwt_token'+encoding+type + "&callback=JSON_CALLBACK")
The Syntax for AngularJS JSONP request is :
$http.jsonp(url, [config]);
where url is "string" type representing Relative or absolute URL specifying the destination of the request. The name of the callback should be the string JSON_CALLBACK, and [config] is Optional configuration object.

Restangular POST fails https:// OPTIONS pass

I was able to convert most of my existing services to use Restangular. Everything apart from POST is working properly.
Original POST service that works
app.service('APIService', function($http, $q){
...
this.post = function(api, route, params){
var d = $q.defer();
$http({
url : base_urls[api] + route,
method : 'POST',
data : params,
withCredentials: true,
useXDomain : true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data){
d.resolve(data);
try{
toastr.success(toastMsg[route].win, 'Success');
} catch(err){}
}).error(function(data){
d.reject(data);
try{
toastr.error(toastMsg[route].fail, 'Whoops');
} catch(err){}
});
return d.promise;
}
});
Which is used like this:
app.controller('AuthController', function($scope, APIService){
$scope.login = function(username_or_email, password, redirectUrl){
APIService.post('root', '/login', {
'username_or_email' : username_or_email,
'password' : password
}).then(function(r){
if(r.success){
window.location = redirectUrl;
}else
{
// handle this
}
});
};
});
Conversion to Restangular
app.controller('AuthController', function ($scope, toastrFactory, Restangular) {
$scope.login = function (username_or_email, password, redirectUrl) {
var login = Restangular.one('auth'),
creds = {
'username_or_email': username_or_email,
'password': password
};
login.post('login', creds).then(function (r) {
window.location = redirectUrl || '/profile';
}, function () {
toastrFactory.error(['Error', 'Login not successful'])
})
};
});
The above fails the pre-flight OPTIONS pass, and gives up. What is the difference between my original service and the Restangular call I'm trying to use?
Worth noting I did set default config params for Restangular (to mirror the original service)
RestangularProvider.setBaseUrl('https://dev.foo.com/');
RestangularProvider.setDefaultHttpFields({
withCredentials: true,
useXDomain : true,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
});
What's strange is my Restangular GETs that require credentials on https:// WORK, and successfully pass the OPTIONS phase, and manage to send cookie data.
Any help is appreciated. Thanks.
I'm not sure about the actual route you are trying to reach, but the Restangular.one('auth') seems like you'd need to define the resource identifier (eg. POST /auth/123?username_or_email=moi).
If you're trying to reach POST /auth?username_or_email=moi (with your cred in the HTTP parameters), then try Restangular.all('auth').
If this didn't solve the problem, please provide the URI you're seeing in the browser's network inspector along with the URI you'd want to reach.

Categories