Angular Translate - How to addPart() with $urlLoader? - angularjs

I'm using staticFilesLoader with partialLoader wich is working really good! So the concept of addPart(home) method in partialLoader says that you do not need to load all the translate table.
Starting for that point. I'm gonna use a rest service now and my question is How to send to the rest service the parameter for just retrieving me the table translate for my specific section, in this example home.
Source Code from angular translate
function $translateUrlLoader($q, $http) {
'use strict';
return function (options) {
if (!options || !options.url) {
throw new Error('Couldn\'t use urlLoader since no url is given!');
}
var requestParams = {};
requestParams[options.queryParameter || 'lang'] = options.key;
return $http(angular.extend({
url: options.url,
params: requestParams,
method: 'GET'
}, options.$http))
.then(function(result) {
return result.data;
}, function () {
return $q.reject(options.key);
});
};
}
The code above doesn't have any extra parameter.
NOTE: Maybe in the specific case of urlLoader with partialLoader you should request all the table translate from the REST and only manage the parts in the frontend. Please tell me about this note if makes any sense.

Related

sending headers using $resource in angular js

I want to send headers each time for CRUD operation from factory side.
Here is my factory
var appangular.module("LifeStyleFactModule",["ngResource"]);
app.constant("RES_URL", "http://localhost:9090/")
app.factory("CategoryFactory",function($resource,RES_URL){
var categoryinfo;
var categoryresource=$resource(RES_URL+"category/:id",{"id":"#id"},{update:{method:"PUT"}});
return{
getcategory:function(){
categoryinfo=categoryresource.query();
return categoryinfo;
},
addcategoryItem:function(categoryItem){
var category = new categoryresource(categoryItem);
category.$save(function(respdata){
categoryinfo.push(respdata);
},function(respdata){
});
},
deletecategoryItem:function(idx,id){
var category=new categoryresource({"id":id});
category.$delete(function(){
categoryinfo.splice(idx,1);
},function(){
})
},
updatecategoryItem:function(categoryItem,idx){
var category=new categoryresource(categoryItem);
category.$update({"id":categoryItem._id},function(data){
categoryinfo[idx]=data;
},function(){
})
}
}
})
the above functionality is working well. Now i want to send the token in the headers. How can i do that.
I have tried to do it by the following way
var categoryresource=$resource(RES_URL+"category/:id",{"id":"#id"},{update:{method:"PUT"},headers:{"token":"#token}});
but not getting how to send the token for CRUD operation.
Is procedure is correct, if so how can i send tokens.
Else let me know the way.
Instead of above method i tried the following way as
$resource(RES_URL+"category",{},{query:{method:"get",isArray:true,headers:{"token":token}}}).query({},function(res){});
this is working but the procedure for the first procedure.
Please after answering mark it as duplicate or down vote
dont say ( / { such things are missing.
The best solution as to me is to use interceptor. Here is a way to send token in headers, I've used in one of my projects.
angular
.module('app.core')
.config(config);
config.$inject = ['$httpProvider'];
function config($httpProvider) {
$httpProvider.interceptors.push(interceptor);
}
interceptor.$inject = ['$q', '$injector', 'AuthModel'];
function interceptor($q, $injector, AuthModel) {
return {
request: function (config) {
config.headers.Authorization = AuthModel.token;
return config;
},
responseError: function (rejection) {
}
};
}
Added a jsfiddle to demonstrate
https://jsfiddle.net/Sergey_Mell/c47js1zc/
Just click the Send button and check the request headers in developer tools

Store domain in one place in angular js service

I have the following example method in angular service:
function send(data) {
return $http({
method: 'POST',
url: 'https://test.domain/test/send',
data: $httpParamSerializerJQLike(data)
});
}
The domain that is https://test.domain/test is the same for all the services in my app. I do not want to write it every time in every services. I can abstract it in a constant and inject it in every service but I wonder if there is more clever solution. Is it possible to store the domain part in an interceptor or any other suggestions are welcome. Please provide code examples as I am quite new to angular. Thanks
I'd say rather than abstracting the values out into a constant, you should abstract the $http call into a service. Then you can just inject that service into all of your other services in place of $http. For example:
angular.module('myApp').factory("myHttp", ["$http", function ($http) {
return function (config) {
config.url = "https://test.domain/test" + config.url;
return $http(config);
};
}]);
So effectively what this service is doing is proxying calls to $http, but prepending your common URL to the beginning - this would allow you to change your example code to:
function send(data) {
return myHttp({
method: 'POST',
url: '/send',
data: $httpParamSerializerJQLike(data)
});
}
Of course, this is just one example of how you could do an abstraction like this - the myHttp service could take any form you like, depending on what would be most convenient for you. I think this is a better solution than using an interceptor in this case, as it allows you to pick and choose when you use it, rather than it being applied to every single HTTP request.
create an interceptor and on requests change the url.
angular.module('app').factory('domainInterceptorService', [
function () {
var request = function (config) {
config.url = 'https://test.domain/' + config.url;
}
return config;
}
return {request: request};
});

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!

AngularJS : How to inject a service into a factory

I have a REST backend which provides a hashmap of API methods. This allows the front end to use a keyname to map to the API method instead of needing to know the entire REST url.
Ex:
{
CHARGE.GET_CHARGE_INFO: /provider/charge/getChargeInfo/{{providerId}}/{{chargeId}}
CHARGE.LIST_CHARGES: /provider/charge/listCharges/{{providerId}}
CHARGE.LIST_TYPES: /provider/charge/listTypes
}
There is a service which is responsible for loading the hashmap from the REST API.
app.service('preloader', function ($http, globals, $interpolate, $q) {
var self = this;
var endPointsList = $http.get(globals.apiPath + globals.endPointsPath, {}).success(function (data) {
self.endPoints = data;
});
return {
endPointsList: endPointsList,
getResourceEndPoint: function( endPoint ){
if (!self.endPoints[endPoint]) {
// To avoid misleading errors
throw ("Endpoint not found. \r\nEndpoint: " + endPoint + "\r\nFound: " + self.endPoints[endPoint]);
}
// reformat
return globals.apiPath + self.endPoints[endPoint].replace(/{{([^}]+)}}/g, ":$1");
}
};
I'm trying to write a $resource which uses this service, but the problem is when the service is injected into the factory, it has not yet been initialized and consequently calls to the method to retrieve the endpoint throw errors.
app.factory('providerFactory', ['$resource', 'preloader',
function ($resource, preloader) {
return $resource( "", null,
{
"getTypes" : {
method: 'GET',
url: preloader.getResourceEndPoint('PROVIDER.LIST_TYPES')
},
"get": {
method: 'GET',
url: preloader.getResourceEndPoint('PROVIDER.GET_PROVIDER_INFO'),
params: {
providerId: '#providerId'
}
}
}
);
});
Error Msg:
TypeError: Cannot read property 'PROVIDER.LIST_TYPES' of undefined
at Object.getResourceEndPoint (http://localhost:8888/client.git/build/app.min.js:3:8967)
If I step through the code, I see that the factory's preloader.getResourceEndPoint() calls are calling the service before the service has completed its initialization of the endPointsList.
What can I do to avoid this problem? Do I have to use a $q promise? It seems like overkill for something like this. If so then I have to wonder if this is even the right approach to get something like this to work, but I'm not sure what approach to use.
I'm still learning AngularJS so I'm not entirely sure of the correct way to proceed. Ive inherited this code so if it seems that it is convoluted/complicated for nothing, I'd appreciate insights on how to improve it.

Is it valid to use a simple return to send back data from an AngularJS factory?

I have the following two ways and they both seem to work:
angular.module('adminApp')
.factory('TestAccount', function ($http) {
return {
get: function (applicationId) {
return $http({
method: 'GET',
url: '/api/TestAccounts/GetSelect',
params: { applicationId: applicationId }
});
}
}
});
//angular.module('adminApp')
//.factory('TestAccount', function ($http) {
// var TestAccount = {};
// TestAccount.get = function (applicationId) {
// return $http({
// method: 'GET',
// url: '/api/TestAccounts/GetSelect',
// params: { applicationId: applicationId }
// });
// };
// return TestAccount;
//});
The second method came from an answer to a question I asked on stackoverflow. The first way was some changes I made to it.
Can someone tell me which is the more conventional way and if there is any difference between these two. For me the first way seems a bit more clean but I am not sure if I am missing out on some functionality by using it.
I used the following to call the service in both cases:
TestAccount.get(3).then(function (result) {
$scope.testAccounts = result.data;
}, function (result) {
alert("Error: No data returned");
});
Those two approaches are equally valid. I prefer the first variant. No need to start with an empty object, set a property and return the object when you can just return an object with the property.
Like Brian said, they're both equally valid.
The second way is more versatile. It lets you write a service that has multiple functions where some of those functions call other of those functions, in a way that is relatively easy to reason about.
Using that ability in a service defined entirely within a .factory method would probably be a bad idea, and you don't need it in this case anyway. But if you have one service for which you do need that versatility, it may be worth using that style for all services across the board.

Resources