How to add translations to $translateProvider from outside the config? - angularjs

I am new to angular js. For language translation I am using angular-translate service in my work.I am getting the entire translations which I need to assign in $translateProvider by an API call response.I know that I can assign the translations to $translateprovider ($translateprovider.translations ('en',translations) only from config module but I think that an API call from config module is not a good practise.
Below given is my config module.
.config(['$translateProvider', function($translateProvider) {
//fetching session key
var response;
jQuery.ajax({
type: "GET",
url: 'https://abcdefg/session?appKey=123456',
async: false,
success: function(data) {
response = data;
getMetaData(response.sessionKey);
}
});
////fetching data.
function getMetaData(sessionKey) {
jQuery.ajax({
type: "GET",
url: 'https://abcdefg/metadata?sessionKey=' + sessionKey +
'&gid=1.2.3.4',
async: false,
success: function(data) {
dataSet = data; //save response in rootscope variable
}
});
}
$translateProvider.translations('en_US', JSON.parse(dataSet.en_us));
$translateProvider.translations('es_ES', JSON.parse(dataSet.es_es));
$translateProvider.preferredLanguage('en_US');
}
How can this be solved? How can I assign translations to $translateProvider from out side the config module?
Thanks in advance.

Take a look at this answer from the creator of angular-translate, where he states that "[...]there's no way to extend existing translations during runtime with $translate service without using asynchronous loading.[...]"
For more information on asynchronous loading of translations take a look at the documentation. You may even specify your own custom loader to get translations by calling your API.

By many purposes, we may need to add more translations in Services, so I found a way to do that.
We can create another CustomProvider which returns $translateProvider, and then we can inject CustomProvider to Services or Controllers.
// NOTE: Create another Provider returns $translateProvider
.provider('CustomProvider', function($translateProvider) {
this.$get = function() {
return $translateProvider;
};
});
// NOTE: Inject CustomProvider to Service to use
.factory('TranslationService', function(CustomProvider) {
console.log(CustomProvider);
return {
addMoreTranslations: addMoreTranslations
};
function addMoreTranslations(key, translations) {
// Do somethings
CustomProvider.translations(key, translations);
}
});
I succeeded by that way.

Related

How to make two https calls in single controller on page load Angular JS

I am new to Angular JS
I am trying to make two API calls on page load but I want to do one after another once I got the response I want to call another Asynchronous calls. my service looks as below
can you please suggest me what should be the best way to achieve this.
(function(){
"use strict";
var APIservice = function($http,$base64,UtilService,$rootScope){
UtilService.setHeaders($rootScope.globals.currentUser.authdata);
var DataProvider = function(method,url,data){
return $http({
method: method,
url: url,
data:data
}).then(function(response){
console.log(response);
return response.data;
});
};
return {
DataProvider:DataProvider
}
}
var module = angular.module('expframework');
module.factory("APIservice",APIservice);
}());
Thanks in Advance
Just use promise chaining:
APIservice.DataProvider('GET', firstUrl).then(function(data1) {
return APIservice.DataProvider('GET', secondUrl);
}).then(function(data2) {
// ...
});

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};
});

AngularJS: Resource factory and callback function

Hi being new to Angular i'm having difficulty seeing how to handle data when using $resource in a factory. I'm trying to move from $http requests to $resources in my factory.
First i had (simplified code):
.factory('MetadataService', function($http) {
$http({
method: 'OPTIONS',
url: 'http://myurl'
}).success(function(data) {
customized_data = do_some_complex_handling_on_data(data)
callback(customized_data);
});
});
When i try to use a $resource in my factory, it seems that i have to call the do_some_complex_handling_on_data() method in my controller:
.factory('MetadataService', function($resource) {
return($resource('http://myurl', {}, {
metadata: {method: 'OPTIONS'}
}));
});
# controller:
var metadata = do_some_complex_handling_on_data(MetadataService.metadata());
Since i'm gonna use the factory in a lot of controllers for different sections in my application (that's why i made a factory in the first place), i would like to have my factory return the data as i need it. And not have to customize the data after the factory returns it.
question: How do i let my factory call the do_some_complex_handling_on_data() function instead of the controller?
You can use response transformer that $http service provides. A transformer is used to transform the response of $http before it is delivered to the end client.
By default there is a single transformer register that convert json string to json object. You can append your own transformer to this collection and it will be called with the response json object. In your transformer function you can then call any function you want that can transform the data.
metadata: {
method: 'OPTIONS'
transformResponse: appendTransform($http.defaults.transformResponse,
function(value) {
return do_some_complex_handling_on_data(value);
})
}
function appendTransform(defaults, transform) {
// We can't guarantee that the default transformation is an array
defaults = angular.isArray(defaults) ? defaults : [defaults];
// Append the new transformation to the defaults
return defaults.concat(transform);
}
I have taken this code from the docs here
Also read documentation on "Default Transformations" in $http service

Angular JS global config for resource success query

I have implemented resources in my single page angular app which fires to my REST client server. I have made different services for each resource. Now my REST server is sending a value in response header, now I want to know a proper way where I can retrieve that value from headers.
My service code:
app.service('$job', function($resource) {
var job = $resource(service_base_url+'jobs.json/:id');
return job;
});
My controller which is getting headers:
app.controllerProvider.register('JobPostsController',['$scope','$job', function($scope, $job) {
$scope.jobs = {};
$scope.job_titles = {};
$job.query(function(jobs,responseHeaders){
var headers = responseHeaders();
some_function(headers.user);
$scope.jobs = jobs.jobs;
});
}
]);
I am getting headers in my above code, but I don't want to inject it in all controllers. So is there a proper way to do it? Some single config code which will run for all future resources request or some kind of event which can be only triggered when successful resource response with 200 OK
Try interceptor.
I don't know exactly your logic. You could register a global interceptor which intercepts all requests:
angular.module('App', [])
.config(function ($httpProvider){
$httpProvider.interceptors.push(function() {
return {
'response': function(response) {
var headers = response.headers();
some_function(headers.user);
return response;
}
};
});
});
or just register an interceptor which runs only for all requests of this query.
app.service('$job', function($resource) {
var job = $resource(service_base_url+'jobs.json/:id',{}, {
'query': {
method:'GET',
isArray:true,
interceptor: {
'response': function(response) {
var headers = response.headers();
some_function(headers.user);
return response;
}
}
}
});
return job;
});
Side notes:
Should not use $ prefix for your service name as it's reserved for angular, it may conflict with angular future versions.
I guess you need .factory instead of .service
You can set up the service in a run block like:
angular.module('myApp', [])
.run(['$rootScope', '$job',function ($rootScope, $job) {
$rootScope.jobs = {};
$rootScope.job_titles = {};
$job.query(function(jobs,responseHeaders){
var headers = responseHeaders();
some_function(headers.user);
$rootScope.jobs = jobs.jobs;
});
}]);
The only drawback your service is global to the app
I would go with a base service factory. This would allow you to have common service related functionality in one place
app.factory('ServiceBase', function () {
function ServiceBase() {
this.responseHeaders = function responseHeaders(resp){
// todo
};
}
return ServiceBase;
});
app.service('$job', function($resource, ServiceBase) {
var service = function () {
// $job related functions here
};
angular.extend(service, new ServiceBase());
return service;
});
Now anything in the ServiceBase is accessible to the controller and to the service. This allows you to have common functionality, has no new injection dependencies (on the controller), and is easy to extend further.
I think angulrjs response interceptors can help u for this.

Define Service or factory using ngResource to retrieve data from server side?

I'm developing angular web app. And I have this controller which needs to call restful api to do some operations on Users.
Earlier I'm thinking define a service which has some methods: getAllUser( ), getUser(id), saveUser( ), deleteUser( ). these methods will use a ngResource to call rest apis.
But when I look at these methods, it seems to me that I'm just wrapping the ngResource and expose some of his lower level methods: query( ), get( ), save( ), delete( ).
Could someone share some experience about how will you design common services or factories or providers which use ngResource to fetch data from server?
I've been working on an angular project myself. And I'd built a Factory manually, and then ended up using JBoss Forge for my second attempt and that build stuff for me in a pretty nice way, here's what it looked like:
angular.module('myApp').factory('myResource', function($resource){
var urlBase = '/rest/resources';
var resource = $resource(urlBase + '/:RsvpId',{RsvpId:'#id'},{'queryAll':{method:'GET',isArray:true},'query':{method:'GET',isArray:false},'update':{method:'PUT'}});
return resource;
});
That's all there is to it, then when you want to call it, you do something like the following:
$scope.save = function() {
var successCallback = function(data,responseHeaders){
var id = locationParser(responseHeaders);
$location.path('/Resources/edit/' + id);
$scope.status = 'success';
};
var errorCallback = function(data, status, headers, config) {
$scope.status = 'failure';
$scope.statusMessage = 'Saving your resource failed: ' + $scope.errorMessage;
};
myResource.save($scope.resource, successCallback, errorCallback);
};
or to do a get, you'd have this line inside a method:
myResource.get({ResourceId:$routeParams.ResourceId}, successCallback, errorCallback);
or
resource.$remove(successCallback, errorCallback);
Hope that helps.
Let me explain about ngResource...
ngResource is a service from AngularJs and it use at lower lever the $http service, so its very simple to use it when you want to use the RESTFul Resources. Here is my example:
myAppModule.factory('User', ['$resource', function($resource) {
return $resource('/user/:userId'}
]);
So what this code above are doing? This is creating a service that return a resource, the url was mapped, so when you inject and call this service you receive a object with some methods: "GET", "POST", "PUT", "DELETE"... Example:
var users = User.query();
The variable "users", receive all users(and plus it receive some resource features like save, because "users" variable still being a resource object), it's like you make this request (.../user/), ok? All you have to do is call resource, it's very simple.

Resources