I have a code that works perfectly inside a controller but after moving it to service, it seems to not work and crush right after this:
return JSON.parse(window.localStorage.getItem("SavedContacts"));
the service code:
var app = angular.module('myApp', ["ngStorage"]);
app.service('ContactManager', function()
{
this.Contacts={};
this.GetJsonFile = function ()
{
return JSON.parse(window.localStorage.getItem("SavedContacts"));
}
this.Contacts = this.GetJsonFile();
...
}
Thanks for any help.
EDIT:
A sample : http://plnkr.co/edit/jjInJp4lJcC1oCvXZ1oN?p=preview
Related
I have a loading problem in Firebase. I want to display a list of images when I open the view but nothing happens till i go back ( there is a flash and i can see my photo list). It's working but not displaying in the opening.
What am i missing please ?
There is the beginning of my Controller view:
'Use Strict';
angular.module('App').controller('valider_photosController', function($scope, $state, $localStorage, Popup, Firebase, $firebaseObject, $ionicHistory, $ionicPopup, $ionicModal, $cordovaCamera) {
$scope.imagestab = [];
var ref_logements = firebase.database().ref('logements');
var ref_images = firebase.database().ref('images');
ref_logements.child(id_logement).child('images').on('child_added', added);
function added(idxSnap, prevId){
ref_images.child(idxSnap.key).once('value', function(datasnap){
var bidule = datasnap.val();
bidule['key'] = datasnap.key;
$scope.imagestab.push(bidule);
console.log('La valeur'+datasnap.key+'donne '+datasnap.val());
});
};
});
Since firebase works with asynchronous calls, by the time firebase responds with your data the angular cycle had already finished and you won't have your scope updated. You can force it by using $scope.$apply();.
ref_images.child(idxSnap.key).once('value', function(datasnap){
var bidule = datasnap.val();
bidule['key'] = datasnap.key;
$scope.imagestab.push(bidule);
$scope.$apply();
});
There is a tool that integrates angular and firebase in a way that you won't have to be concerned with things such as applying the scope. Its called angularfire. I totally recommend you to start using it in your application.
With angularfire you can get your data simply using
$scope.bidule = $firebaseObject(ref_images.child(idxSnap.key));
or
$scope.images = $firebaseArray(firebase.database().ref('images'));
I created a Factory
.factory('Firebase', function ($firebaseArray, $firebaseObject) {
var ref = firebase.database().ref();
return {
all: function (section) {
var data = $firebaseArray(ref.child(section));
return data;
},
getById: function (section, id) {
var data = $firebaseObject(ref.child(section).child(id));
return data;
},
get: function (section, field, value) {
var data = $firebaseArray(ref.child(section).orderByChild(field).equalTo(value));
return data;
}
};
})
And then in my controller, i replaced like you said :
var ref_logements = firebase.database().ref('logements');
var ref_images = firebase.database().ref('images');
ref_logements.child(index2).child('images').on('child_added', added);
function added(idxSnap, prevId) {
var monimage = Firebase.getById('images', idxSnap.key);
$scope.imagestab.push(monimage);
};
And it Works like a charm ! Thank you again :)
I don't know what it is about injecting factories, but I am having the most difficult time.
I've simulated what I'm attempting to do via this sample plunk http://plnkr.co/edit/I6MJRx?p=preview, which creates a kendo treelist - it works fine.
I have an onChange event in script.js which just writes to the console. That's also working.
My plunk loads the following:
1) Inits the app module, and creates the main controller myCtrl (script.js)
2) Injects widgetLinkingFactory int myCtrl
3) Injects MyService into widgetLinkingFactory
The order in which I load the files in index.html appears to be VERY important.
Again, the above plunk is NOT the real application. It demonstrates how I'm injecting factories and services.
My actual code is giving me grief. I'm having much trouble inject factories/services into other factories.
For example,
when debugging inside function linking() below, I can see neither 'CalculatorService' nor 'MyService' services. However, I can see the 'reportsContext' service.
(function () {
// ******************************
// Factory: 'widgetLinkingFactory'
// ******************************
'use strict';
app.factory('widgetLinkingFactory', ['reportsContext', 'MyService', linking]);
function linking(reportsContext, MyService) {
var service = {
linkCharts: linkCharts
};
return service;
function linkCharts(parId, widgets, parentWidgetData) {
// *** WHEN DEBUGGING HERE, ***
// I CANNOT SEE 'CalculatorService' AND 'MyService'
// HOWEVER I CAN SEE 'reportsContext'
if (parentWidgetData.parentObj === undefined) {
// user clicked on root node of grid/treelist
}
_.each(widgets, function (wid) {
if (wid.dataModelOptions.linkedParentWidget) {
// REFRESH HERE...
}
});
}
}
})();
A snippet of reportsContext'service :
(function () {
'use strict';
var app = angular.module('rage');
app.service('reportsContext', ['$http', reportsContext]);
function reportsContext($http) {
this.encodeRageURL = function (sourceURL) {
var encodedURL = sourceURL.replace(/ /g, "%20");
encodedURL = encodedURL.replace(/</g, "%3C");
encodedURL = encodedURL.replace(/>/g, "%3E");
return encodedURL;
}
// SAVE CHART DATA TO LOCAL CACHE
this.saveChartCategoryAxisToLocalStorage = function (data) {
window.localStorage.setItem("chartCategoryAxis", JSON.stringify(data));
}
}
})();
One other point is that in my main directive code, I can a $broadcast event which calls the WidgetLinking factory :
Notice how I'm passing in the widgetLinkingFactory in scope.$on. Is this a problem ?
// Called from my DataModel factory :
$rootScope.$broadcast('refreshLinkedWidgets', id, widgetLinkingFactory, dataModelOptions);
// Watcher setup in my directive code :
scope.$on('refreshLinkedWidgets', function (event, parentWidgetId, widgetLinkingFactory, dataModelOptions) {
widgetLinkingFactory.linkCharts(parentWidgetId, scope.widgets, dataModelOptions);
});
I am wasting a lot of time with these injections, and it's driving me crazy.
Thanks ahead of time for your assistance.
regards,
Bob
I think you might want to read up on factories/services, but the following will work:
var app = angular.module('rage')
app.factory('hi', [function(){
var service = {};
service.sayHi = function(){return 'hi'}
return service;
}];
app.factory('bye', [function(){
var service = {};
service.sayBye = function(){return 'bye'}
return service;
}];
app.factory('combine', ['hi', 'bye', function(hi, bye){
var service = {};
service.sayHi = hi.sayHi;
service.sayBye = bye.sayBye;
return service;
}];
And in controller...
app.controller('test', ['combine', function(combine){
console.log(combine.sayHi());
console.log(combine.sayBye());
}];
So it would be most helpful if you created a plunk or something where we could fork your code and test a fix. Looking over your services it doen't seem that they are returning anything. I typically set up all of my services using the "factory" method as shown below
var app = angular.module('Bret.ApiM', ['ngRoute', 'angularFileUpload']);
app.factory('Bret.Api', ['$http', function ($http: ng.IHttpService) {
var adminService = new Bret.Api($http);
return adminService;
}]);
As you can see I give it a name and define what services it needs and then I create an object that is my service and return it to be consumed by something else. The above syntax is TypeScript which plays very nice with Angular as that is what the Angular team uses.
I'm writing a basic calculator app on jsfiddle to get some more experience with angular and I wanted to know if injected services can be used like objects to get properties. For example:
angular.module('CalcApp', [])
.controller('CalcVm', CalcVm)
.service('MathOperations', MathOperations);
angular.$inject = ['MathOperations'];
function CalcVm(MathOperations) {
var vm = this;
vm.xyz = '';
//code
}
function MathOperations() {
var addOp = '+';
var subtractOp = '-';
//etc..
}
is it possible to do this in the view:
<div ng-controller='CalcVm as calcVm'>
<button>{{calcVm.MathOperations.addOp}}</button>
</div>
should I bind the service to a variable in the controller?
function CalcVm(MathOperations) {
var vm = this;
vm.xyz = '';
vm.MathOperations = MathOperations;
//code
}
Ok so I've been experimenting with this and I've figured it out.
what worked was the following:
angular.module('CalcApp', [])
.controller('CalcVm', CalcVm)
.service('MathOperations', MathOperations);
angular.$inject = ['MathOperations'];
function CalcVm(MathOperations) {
var vm = this;
vm.MathOperations = MathOperations;
//more code
}
function MathOperations() {
this.addOp = '+';
this.subtractOp = '-';
//etc..
}
notice that I've used the keyword this in the service and I've assigned the injected service to a variable in my controller.
I'm not sure if this is good or bad practice and if anyone knows please edit this answer below the line with further info.
I got problem to inject a service to another one, however when I tested separately it seems work fine then.
My project structure is like this, app.html includes app.js, service1.js, service2.js, and they are placed in order.
Below is my code:
app.js
var aoApp = angular.module('aoApp', []);
aoApp.run(function (permissionService, userService) {
userService.setPermissions("['admin']");
permissionService.print();
});
service1.js
var app = angular.module('aoApp');
app.service('userService', function(){
var user = {
permissions: []
};
this.setPermissions = function(permissions){
user.permissions = permissions;
};
this.getPermissions = function(){
return user.permissions;
};
return this;
});
service2.js
var app = angular.module('aoApp');
app.service('permissionService', function(userService){
var userGrantedPermissions = userService.getPermissions();
//Here always print '[]' rather '['admin']'
console.log(userGrantedPermissions);
this.print = function(){
console.log(userGrantedPermissions);
};
return this;
});
Problem is in service2.js (permissionService), parameter userGrantedPermissions is expected to be ['admin'], however its value keeps the default value '[]', I don't know if do something wrong here, but I tried to tested here, it works! so what's wrong with my code now? why doesn't it work here?
The problem is due to the execution of your code.
var app = angular.module('apps', []);
app.service('s1', function(){
console.log('in s1 ctor');
return this;
});
app.service('s2', function(s1){
console.log('in s2 ctor');
return this;
});
app.run(function(s1, s2){
console.log('executing run');
});
This will print:
in s1 ctor
in s2 ctor
executing run
Since the ctors run before the run method.
Your Fiddle example doesn't run the code the same way you do in your original example.
The original example does this in the ctor:
var userGrantedPermissions = userService.getPermissions();
Which is executed before the run method and therefore returns the init value [].
Your fiddle executes a method and doesn't run anything in the ctor.
Check out this JSFIDDLE.
I have following code, which basically loads messages from the server via $http.get request in the service and then used in the i18n filter. Filter was working fine with angular version 1.2.24 but after updating to 1.3.5 it no longer works.
I was wondering if anyone ran into similar issue and can shine some light on this.
var module = angular.module('myApp', [])
.factory('MessageFactory', function ($http, $locale, $log) {
var messages = {};
$http.get("/i18n/" + $locale.id + "/list", {cache: true}).success(function(data) {
$log.debug("Getting messages for", $locale.id);
messages = data;
});
return {
getMessage: function (key) {
return messages[key];
}
}
})
.filter('i18n', function (MessageFactory) {
return function (key) {
return MessageFactory.getMessage(key);
}
});
Html Code
<h2>{{'message.page.title'|i18n}}</h2>
Finally after couple of hours of digging I changed
.filter('i18n', function (MessageFactory) {
return function (key) {
return MessageFactory.getMessage(key);
}
});
to
.filter('i18n', function (MessageFactory) {
function filterFn(key) {
return MessageFactory.getMessage(key);
}
filterFn.$stateful = true;
return filterFn;
});
Notice filterFn.$stateful that's what did the trick.
I couldn't find docs proof of that, but it looks like angular 1.3.x executes code inside modules only when it firstly used, and <= 1.2.x do it when app started.
Looks like you need to change your code to load locale files in app.run() method;
Something like this: http://codepen.io/anon/pen/vELogx