I just recently started learning angular and i'm a bit lost with this code, could some one help me with this. Like, how i can modify it to use my en_US.json which is located at locale/locale-en_US.json.
.factory("$translateStaticFilesLoader", ["$q", "$http",
function(a, b) {
return function(c) {
if (!c || !angular.isString(c.prefix) || !angular.isString(c.suffix)) throw new Error("Couldn't load static files, no prefix or suffix specified!");
var d = a.defer();
return b({
url: [c.prefix, c.key, c.suffix].join("../locale/locale-"),
method: "GET",
params: ".json"
}).success(function(a) {
d.resolve(a)
}).error(function() {
d.reject(c.key)
}), d.promise
}
$translateProvider.preferredLanguage('en_US');
}
]);
I'm feeling a little dumb. I managed to fix my code and the solution was >
app.js(main)
app.config(['$translateProvider', function ($translateProvider) {
$translateProvider.preferredLanguage('en_US');
$translateProvider.useStaticFilesLoader({
prefix: '../locale/locale-',
suffix: '.json'
});
}]);
services.js
app.factory("$translateStaticFilesLoader", ["$q", "$http",
function(a, b) {
return function(c) {
if (!c || !angular.isString(c.prefix) || !angular.isString(c.suffix)) throw new Error("Couldn't load static files, no prefix or suffix specified!");
var d = a.defer();
return b({
url: [c.prefix, c.key, c.suffix].join(""),
method: "GET",
params: ""
}).success(function(a) {
d.resolve(a);
}).error(function() {
d.reject(c.key);
}), d.promise;
}
$translateProvider.preferredLanguage('');
}]);
I just needed to copy the static translate from the original source and paste it to my services and leave all the parameters empty.
Static file loading with $translate is handled by an additional external *.js file that you need to load in. This contains the $translateStaticFilesLoader factory mentioned here.
You can manually copy in the factory like #ALoppu did, but a better approach is to actually load the external script right after angular-translate.js:
<script src="vendor/angular/angular-translate.min.js"></script>
<script src="vendor/angular/angular-translate-loader-static-files.min.js"></script>
You can get the latest copy of angular-translate-loader-static-files.min.js on GitHub here.
Related
var templatePath = require('../templatePath');
var controllerPath = require('../ControllerPath');
$scope.loadNgModules = function(templatePath, controllerPath) {
var files = [];
if (templatePath) files.push({ type: 'html', path: templatePath });
if (controllerPath) files.push({ type: 'js', path: controllerPath});
if (files.length) return $ocLazyLoad.load(files)
};
ocLazyLoad is not working When I use webpack for minification. Since I guess ocLazyLoad accepts only path of the template and controller but webpack is bundling both template and controller into the single minified file so it fails to load.
Webpack plugin name : uglifyjs-webpack-plugin'
Is there any way to accomplish this problem using ocLazyLoad.? Can I load a string of template and controller file other than considering path.?
As per my understanding basically ocLazyLoad accepts only path of the script and template files
So I have resolved this issue by using $templateCache
if (angular.isString(templatePath) && templatePath.length > 0) {
angular.forEach(angular.element(templatePath), function (node) {
if (node.nodeName === "SCRIPT" && node.type === "text/ng-template") {
$templateCache.put(node.id, node.innerHTML);
}
});
}
Hope this will helps to someone :-)
I am using gulp to run and build to run my application. I am getting file contents using $http service in my index.js file and then setting value of a variable like
window.variablex = "http://localhost:8080/appname".
here is how I am doing it (in index.js)
(function ()
{
'use strict';
angular
.module('main')
.controller('IndexController', IndexController);
function IndexController($http){
$http.get('conf/conf.json').success(function(data){
window.variable = data.urlValue;
}).error(function(error){
console.log(error);
});
}
});
And I've created a factory to call the rest APIs of my backend application like
(function(){
'use strict';
angular
.module('main')
.factory('testService',['$resource',testService]);
function agentService($resource){
var agents = $resource('../controller/',{id:'#id'},
{
getList:{
method:'GET',
url:window.variable+"/controller/index/",
isArray:false
}
});
Now, I except a rest call to made like
http://localhost:8080/appname/controller
But it always sends a call like http://undefined/appname/controller which is not correct.
I can get the new set value anywhere else, but this value is not being set in resource service objects somehow.
I am definitely missing something.
Any help would be much appreciated
As you are using Gulp, I advise you to use gulp-ng-config
For example, you have your config.json:
{
"local": {
"EnvironmentConfig": {
"api": "http://localhost/"
}
},
"production": {
"EnvironmentConfig": {
"api": "https://api.production.com/"
}
}
}
Then, the usage in gulpfile is:
gulp.task('config', function () {
gulp.src('config.json')
.pipe(gulpNgConfig('main.config', {
environment: 'production'
}))
.pipe(gulp.dest('.'))
});
You will have this output:
angular.module('myApp.config', [])
.constant('EnvironmentConfig', {"api": "https://api.production.com/"});
And then, you have to add that module in your app.js
angular.module('main', [ 'main.config' ]);
To use that variable you have to inject in your provider:
angular
.module('main')
.factory('testService', ['$resource', 'EnvironmentConfig', testService]);
function agentService($resource, EnvironmentConfig) {
var agents = $resource('../controller/', {id: '#id'},
{
getList: {
method: 'GET',
url: EnvironmentConfig + "/controller/index/",
isArray: false
}
});
}
#Kenji Mukai's answer did work but I may have to change configuration at run time and there it fails. This is how I achieved it (in case anyone having an issue setting variables before application gets boostrap)
These are the sets that I followed
Remove ng-app="appName" from your html file as this is what causing problem. Angular hits this tag and bootstraps your application before anything else. hence application is bootstratped before loading data from server-side (in my case)
Added the following in my main module
var injector = angular.injector(["ng"]);
var http = injector.get("$http");
return http.get("conf/conf.json").then(function(response){
window.appBaseUrl = response.data.gatewayUrl
}).then(function bootstrapApplication() {
angular.element(document).ready(function() {
angular.bootstrap(document, ["yourModuleName"]);
});
});
This will load/set new values everytime you refresh your page. You can change conf.json file even at runtime and refreshing the page will take care of updating the values.
I have a json file of events setup like this:
{
2: {
sched_conf_id: "38",
title: "Coffee Break",
},
3: {
sched_conf_id: "39",
title: "registration",
},
}
I setup and angular factory like this:
.factory('eventFactory', ['$resource',
function($resource) {
return {
query: function(event_id) {
return $resource('/assets/events.json', {}, {
query: { method: 'GET', params: {id:event_id}, isArray: false }
}).query();
}
}
}
])
and lastly I have my angular controller which calls the query method from the factory with the id being the id from the url:
.controller('eventCtrl', function($scope, $routeParams, eventFactory) {
var eventId = $routeParams.event_id;
$scope.eventData = eventFactory.query(eventId);
})
The return data seems to be just the entire events.json file rather than just the specific id I want to query for in the parameters. In the params I am trying id but that is obviously not correct. Using this setup how can I return just the data from event_id: 2?
Assuming your production scheme is going to be fetching just a static file that doesn't do anything with arguments passed in, you need to extract the record you need after it's returned from the server.
Basically, you're requesting something like http://yourhost.com/assets/events.json?event_id=3 and if it's just a static file, the server can't do anything with that parameter. In practice, I would think you'd actually be requesting a response from a web service that can handle that, in which case your client-side code would probably work as-is.
In this specific case, however, I would think that you could handle this with an interceptor. Something like this:
.factory('eventFactory', ['$resource',
function($resource) {
return {
query: function(event_id) {
return $resource('/assets/events.json', {}, {
query: { method: 'GET', isArray: false,
interceptor: {response:
function(data){ var d = JSON.parse(data);
return d[event_id];
}
}
}
});
}
}
}
])
I don't have an environment set up to test this at the moment, but I think it should work. I have a couple places in my own code where I do something similar, for other reasons.
I am using the following code, and I looking to push the headers first, followed by the request. Using JQuery, I just add beforeSend, works fine. But i have changed over to AngularJS (which I am loving... mostly) and I get confused about interceptors!
What confuses me, is if i want to send the header first, where do I tell it, where to send the header. Looking at examples, which is not many, relating too 'beforeSend', I have either not understood, or have not seen any that fits my issue.
Code:
App.factory('postCemment', function($q,requestInterceptor, $http) {
return {
fnsend: function(sid, author, comment, callback) {
$http.Provider.interceptors.push(requestInterceptor);
$http.post("https://api.appery.io/rest/1/db/collections/comments/",
{
headers: {"Content-Type": 'application/x-www-form-urlencoded'},
params: {comment_author : author, comment : comment, statement_id : sid}
})
.success(function(commentres) {
callback(commentres);
})
}
}
})
App.factory('requestInterceptor', function() {
return {
'request': function(config) {
config.headers = {"X-Appery-Database-Id": dbid}
console.log(config);
return config;
}
}
})
App.controller('addCommentBox', function($scope, $http, $routeParams, postCemment) {
$scope.addCommentData = function() {
postCemment.fnsend($routeParams.id,$scope.aurhor,$scope.comment, function(res) {
console.log(res);
})
}
})
If I try without any type of interceptor, I just get an error that database is not specified, even though I can see it in the headers in the browser dev screen.
I have used $q and defer before, and I do read that is may be required, as some examples do not use it, but this is where the confusion is. Even with a defer, at what point do I defer?
Thanks in advance.
Andrew
I am facing a weird issue in a requirejs/backbonejs application. I have a Globals.js file which returns reusable utilities. It looks something like this.
define(
['newapp/routers/index', 'newapp/controllers/index', 'newapp/utilities'],
function(Router, Controller, Utilities) {
return {
router: new Router({controller: Controller}),
utilities: Utilities,
navigate: function(path, opts) {
this.router.navigate('app/' + path, opts);
}
}
})
When I require this module in modules that return Backbone Views, it is able to resolve Globals to an object and call methods on it. However, when I try to include it in a module that returns another object, it's resolved to undefined.
For example the code below is able to resolve Globals to the properties it exposes
define(
['marionette', 'templates', 'newapp/globals', 'newapp/views/Loader'],
function(M, T, Globals, mixins){
"use strict";
return M.ItemView.extend(
_.extend({}, mixins, {
template: T.brandPageInfo,
events: {
'click #getProductsForBrands': 'getProductsForBrands',
'click button[id^="goto__"]': 'actionOnGotoButtons'
},
onRender: function() {
this.flatIconsOnHover();
},
getProductsForBrands: function(e) {
e.preventDefault();
var searchQuery = this.model.get('name');
Globals.navigate('search?q=' + searchQuery, {trigger: true});
}
})
)
})
But the code below gives an error: Globals is undefined
define(
[
'newapp/collections/Boards', 'newapp/globals'
],
function(
BoardsCollection, Globals
) {
var boardsList;
return {
ensureBoardList: function() {
var defer = $.Deferred();
if (!boardsList || (boardsList && !boardsList.length)) {
boardsList = new BoardsCollection();
boardsList.fetch({
data: {_: (new Date()).getTime()},
success: function (boardsListCbData) {
boardsList = boardsListCbData;
defer.resolve(boardsList);
}
})
} else {
defer.resolve(boardsList);
}
return defer.done(function (boardsList) {
//make the boardsList usable for direct UI rendering by any view
return Globals.utilities.getFormattedBoardsCollection(boardsList);
});
}
}
})
How do I make Globals accessible in the second example?
Make sure you don't have any circular dependencies e.g.:
globals depends on newapp/controllers/index
newapp/controllers/index depends on the last module you displayed (we'll call it module M)
module M depends on global
Since each module depends on the other, the only thing RequireJS can do is set one of them to undefinedto "break the cycle" and get the other modules to load.
As far as I can tell, this is the most probable source of your problem, not the fact that you're returning another object.