Angular service, $http.get() with a route param? - angularjs

Typically when asking the API endpoint for JSON, I'd write something like this:
factory('User', function($http) {
return {
get: function() {
return $http.get('/api/users');
}
}
});
However, how can I add a route parameter to get a specific user (RESTful show method)?
i.e. /api/users/1 to get user number one. But I want it to be dynamic based on the logged in user.

You can use the $resource factory instead of using $http. As stated in the documentation $resource is:
A factory which creates a resource object that lets you interact with
RESTful server-side data sources.
To do what you want, you can simply declare it like this:
factory('User', function($resource) {
var UserResource = $resource('/api/users/:id');
return UserResource;
});
Usage:
.controller('Ctrl', function($scope, User) {
// Sends GET /api/users/1
User.get({id: '1'}).$promise.then(function(user) {
// expects a single user data object
console.log(user);
});
// Sends GET /api/users
User.query().$promise.then(function(users) {
// expects an array of user data objects
console.log(users);
});
});

Related

How to contact a non-standard API using Angular ngResource

The API I am using requires a non-standard where clause if I try to search for a particular non-id field. The endpoint I need is:
http://127.0.0.1:4001/api/testusers/findOne?userName=Anton
So this will find me the first record in the testusers table whose column (userName) = 'Anton'.
My standard service is:
angular.
module('shared.testUser').
factory('TestUser', ['$resource',
function($resource) {
return $resource('http://127.0.0.1:4001/api/testusers/:id', {id:'#id'},//parameters
{
update: {
method: 'PUT' // To send the HTTP Put request when calling this custom update method.
}
});
}
]);
and my calling function is:
self.checkUsersEntryDirection = function(){ //NOT WORKING
self.testuser = TestUser.get({ username: 'anton' }, function() {
console.log(angular.toJson(self.testuser));
}); // get() returns a single entry
}
Clearly this doesn't work and I can't use the standard get approach. Can anyone think how this can be achieved?
You could create a secondary factory TestUserByName, and make the following changes:
angular.
module('shared.testUser').
factory('TestUserByName', ['$resource',
function($resource) {
return $resource('http://127.0.0.1:4001/api/testusers/findOne?userName:username', null,
{
update: {
method: 'PUT' // To send the HTTP Put request when calling this custom update method.
}
});
}
]);
Call the get action method with two parameters:
var params = {id: "findOne", username: "anton"};
self.checkUsersEntryDirection = function(){
self.testuser = TestUser.get(params, function() {
console.log(angular.toJson(self.testuser));
}); // get() returns a single entry
}
The id parameter will override the default and username parameter will be added as a query string.
From the DOCS:
Each key value in the parameter object is first bound to url template if present and then any excess keys are appended to the url search query after the ?.
Given a template /path/:verb and parameter {verb:'greet', salutation:'Hello'} results in URL /path/greet?salutation=Hello.
--AngularJS ngResource $resource Service API Reference

How can I get specific value from $http.get in AngularJS

I have a simple question. When I use $http.get in angular controller, how can I use a specific value from the results? Let's say that I am getting username and password and I want to compare each one individually.
app.controller("loginController", function ($scope, $http) {
$scope.submit = function () {
$http.get("../Views/userAuthentecation.aspx")
.then(function (response) {
$scope.members = response.data;
});
}
});
From the above controller, I am using the userAuthentecation.aspx to read from database in the behind code and just display the results as json format. So, the $scope.members is actually a json format data contains username and password.
Well generally we assign an entire response to a single object like you did
$scope.members = response.data;
but lets say if you have 3 objects in response.data and you want them all to be in the different objects than you can simply assign them to different objects like below
$scope.id = response.data.id;
$scope.username = response.data.username;
$scope.members = response.data.password;
once the data is assigned to $scope.objects than you can do with it whatever you like but Since you have authentication code in your controller i suppose you are trying to make an authentication system. well in that case once the login form is filled its been send to a function in controller for authentication for example
<form name="form" ng-submit="login()" role="form">
once the controller gets the request you can either process it in the same function or you can send it to authentication service which is usually a factory to perform a specific task in this case it will check the user crediantials.
$scope.login = function () {
$scope.dataLoading = true;
AuthenticationService.Login($scope.username, $scope.password, function(response) {
if(response.success) {
AuthenticationService.SetCredentials($scope.username, $scope.password);
$location.path('/');
} else {
$scope.error = response.message;
$scope.dataLoading = false;
}
});
};
the above function is calling another factory for authenticating the user credentials, the factory AuthenticationService will be called which will pass the parameters to Login() function. function within the factory can be called like this
AuthenticationService.login()
once the credentials are checked and verfied and response code is 200 which means ok then entered creditals will be passed to
AuthenticationService.SetCredentials($scope.username, $scope.password);
which will generated encrypted cookie
hope this will give a little understand about authentication and comparing the response data, the entire workig authentication example can be found here

Retrieving data using $http.post

Hi I want to get data from my json file using post method(which is working 5n with get method)
'use strict';
angular.module('myapp').controller('lastWeekWinners',function($http){
var vm= this;
$http.post('http://localhost:9000/json/sample.json').then(function(data){
vm.winnerData=data.data.data;
},function(error){
console.log(error);
});
});
the about code is give error
which means can't we use post method to get the data
This is how u can use the post method in your controller:
'use strict';
angular.module('myapp').controller('lastWeekWinners', controller){
function controller($scope,fetch){
var vm= this;
vm.show = show;
}
function show() {
return fetch.show()
.then(function successCallback(data){
vm.winnerData = data;
}
}, function errorCallback (response) {
console.log(response.statusText);
});
}
});
and in your service :
angular
.module('service',[])
.service('fetch', Service);
function Service($http) {
var fetch = {
show : show
}
return fetch;
function show() {
return $http.get('http://localhost:9000/json/sample.json')
.then(getShowComplete)
.catch(getShowFailed);
function getShowComplete(response){
return response.data;
}
function getShowFailed(error){
console.log("Error:" + error);
}
}
First of all, the difference between GET/POST:
GET is used for getting data, POST is used for saving (and sometimes updating) data. So if you just want to get the json, use GET.
Regarding the specific problem you have here, if you look carefully, you get a 404 code. that means the route was not found. (You can read more about HTTP status code here: http://www.restapitutorial.com/httpstatuscodes.html)
Not sure what server you're using but usually, you're not only defining a route but also the verb of the route (GET/POST/PUT/DELETE), so if you have a route defined like:
GET /users/
This will only work for GET requests, if you try to post for the same route you'll get 404. You have to define the same route for the POST verb.
You can read more about http verbs here: http://www.restapitutorial.com/lessons/httpmethods.html
To do $http.post you need a back end API(PHP,Node Js etc),that system catch your desired post data and save into the db or JSON(Read/Write Method).
Static JSON data just read only possible not write.
Or used Browser $window.localStorage to save data.

Unable to create POST request to REST API with $resource in angularjs

I am learning about the MEAN stack, and have created a REST API which posts a review to a collection in MongoDB.
I have defined a service as given:
angular.module('myApp')
.constant('baseURL', 'http://localhost:8080/');
angular.module('myApp')
.service('addReviews', ['$resource', 'baseURL', function($resource, baseURL) {
this.getReviews = function() {
return $resource(baseURL+'reviews/', null, {'save': {method: 'POST'}});
};
}]);
Now, I am calling this service from my controller:
angular.module('myApp', ['ngResource'])
.controller('reviewController', ['$scope', 'addReviews', function($scope, addReviews) {
$scope.reviewSubmit = function() {
$scope.receivedReviews = false;
var review = {
// some data
};
$scope.reviews = addReviews.getReviews().query(
function(response) {
$scope.reviews = response;
$scope.receivedReviews = true;
},
function(response) {
$scope.reviews = response;
// print error message
}
);
console.log($scope.reviews); // showing empty array
};
}]);
In routes.js, I have configured my route as:
var Reviews = require('./models/reviews');
...
app.post('/reviews', function(req, res) {
Reviews.create(req.body, function(err, post) {
if (err) {
return res.send(err);
}
return res.json(post);
});
});
I am trying to post a new review to the Reviews collection. However, $scope.reviews is showing an empty array. I logged the requests, and it shows a GET request is being to /reviews instead of POST. I think I should use save() instead of query(), but I have seen some tutorials online where they used query() despite the method being PUT/POST in the service. I am really confused. Can anyone point out how I can post the data (in var review) to the Reviews collection?
There are some issues with your code on the angular side of things.
You want to use $resource as an all-purpose object to communicate with the API. It has built-in functionality to:
query: get all resources from a given API endpoint
get: a single resource, usually by specifying that resource's id
save: post, with an object sent across in the body of the request. NOTE: you don't need the {'save': {method: 'POST'}} in your $resource configuration, you get it for free.
remove and delete: self-explanatory
So you'd want to set up your reviews factory (incl. url constant) like:
angular.module('myApp', ['ngResource'])
.constant('baseURL', 'http://localhost:8080/')
.factory('Reviews', ['$resource', 'baseURL', function($resource, baseURL) {
return $resource(baseURL+'reviews/:id', {id: '#id'});
}]);
If you want to have access to all saved reviews in your controller, as $scope.reviews, you'd do something like:
angular.module('myApp')
.controller('reviewController', ['$scope', 'Reviews', function($scope, Reviews) {
// hit API endpoint to get all reviews
// will have to have app.get('/reviews', function(req, res) {...})
// configured in your node code
Reviews.query(function(data) {
$scope.reviews = data;
}, function(error) {
console.log(error);
});
// and if you want to take a user-written review, say $scope.userReview,
// from the view and save it to the database on click function submitReview()...
$scope.userReview = {
message: '',
createdTime: null
};
// ^ not sure what your ReviewSchema looks like on the backend, but for example...
$scope.submitReview = function() {
if ($scope.userReview.message.length) {
$scope.userReview.createdTime = Date.now();
Reviews.save($scope.userReview);
// ^ this will make POST request with the $scope.userReview object as the request body
}
};
}]);
The create method on your back end looks fine. The object (or maybe just string) you send across will have to match your review schema. You may want to log the request body to make sure you're getting what you expect.
Have a look at this short post on using $resource to interact with RESTful APIs, and (the slightly more confusing) angular $resource docs, for more information on the $resource service.
Hope this helps you!

Using [] square brackets as part of a parameter in $resource GET call to API in Angular is not working

I am trying trying to GET user data from an ajax-localized REST api that wants parameters like so:
/api/activity?filter[user_id]=1
I have a factory set up with query parameters like so:
angular.module('app')
.factory('Activity',function($resource){
return $resource(ajaxInfo.api_url+'activity',
{ // Query parameters
filter: {
'[user_id]': '#userId'
},
},
{
'query':{
method:'GET',
headers: {
'X-WP-Nonce': ajaxInfo.nonce
},
isArray: false
}
});
})
I'm console.logging it in a template like so:
$scope.userOne = Activity.query({userId:1});
console.log($scope.userOne)
It's returning
http:site.dev/api/activity?filter=%7B%22%5Buser_id%5D%22:%22#userId%22%7D&userId=1".
Any idea what I'm doing wrong?
Here's what I did to fix this:
I created a factory called "CurrentUser" this factory basically returns the current user's object from an api.
Then I created a controller that passed the parameters to the Activity factory when I wanted to filter the activity by that user id.
$scope.userInfo = function(){
//call the CurrentUser and see if it's available and return it as u
CurrentUser.instance().then(function(u) {
//now query the activity factory and pass the filter as a string along with the user id as u.id
Activity.query({'filter[user_id]':u.id}, function(res){
$scope.userOne = res ;
console.log($scope.userOne);
});
})
};
$scope.userInfo();

Resources