I have a service with the following code:
.service('ChatService', function() {
return { //Gets Data from controller
sendData: function(data) {
this.chatData = data;
console.log('this.chatData: '+this.chatData);
},
chats: this.chatData,
getChats: function() {
return this.chatData;
},
getChat: function(chatId) {
for(i=0; i<this.chats.length; i++) {
if (this.chats[i].id == chatId) {
return this.chats[i];
}
}
}
}
})
The Important thing here is that sendData retrieves info
[{id: 1, message: "Chat Message 1"},{id: 2, message: "Message 2"}]
from the controller. The getChats in Services is then called $scope.chats = ChatService.getChats(); by the same controller to show in the template.
When that item is clicked a new page with more info is to show hence the getChat and getChats function in the service.
The code in the controller for the page to load more details is
$scope.chatId = $stateParams.chatId;
$scope.chat = ChatService.getChat($scope.chatId);
However I'm getting error cannot read property length of undefined. Now if I change the chats: this.ChatData in the services to
chats: [{id: 1, message: "Chat Message 1"},{id: 2, message: "Message 2"}]
It works like a charm but I need it to display in real time what is in the controller because I'm downloading and receiving info from the server that will be updated in real time for a chat app.
Use angular.copy to update the reference:
app.service('ChatService', function() {
//Gets Data from controller
this.sendData = function(data) {
//this.chatData = data;
//console.log('this.chatData: '+this.chatData);
//Use angular.copy
angular.copy(data, this.chats);
};
this.chats = [];
this.getChats = function() {
return this.chats;
};
this.getChat = function(chatId) {
for(i=0; i<this.chats.length; i++) {
if (this.chats[i].id == chatId) {
return this.chats[i];
};
};
};
});
By using the angular.copy to update the array reference, controllers that have previously fetched the reference will get updated.
For more information, see AngularJS angular.copy API Reference.
Related
I need to pass data to an array in service after getting from server. The controller runs the function to retrieve data as shown
.controller("messagesController", function($scope, $stateParams, RegisterP) {
// function here retrives data from the RegisterP parameter above calling another service
$scope.messagepool = [ 1, 2]; //I add the data I get here to an array
})
This array then gets sent to a service
.service('ChatService', function() {
return {
chats: [
{
id: "1",
message: "Chat Message 1"
}
],
getChats: function() {
return this.chats;
},
getChat: function(chatId) {
for(i=0;i<this.chats.length;i++){
if(this.chats[i].id == chatId){
return this.chats[i];
}
}
}
}
})
That in turn sends that to a view/views. I need to know how to send the info from controller so its the one occupying the chats: [] so the the views are updated in REAL-TIME. Using the Ionic Framework.
Bonus: I haven't researched having the get function in controllers constantly poll the incoming messages however if you can tell me that it'll be helpful and save time.
controller
.controller("messagesController", function($scope, $stateParams, RegisterP,ChatService) {
// function here retrives data from the RegisterP parameter above calling another service
$scope.messagepool = [ 1, 2]; //I add the data I get here to an array
ChatService.sendData($scope.messagepool);
});
service
.service('ChatService', function() {
return {
sendData:function(data){
this.chatData=data;
console.log(this.chatData);
// this.getChats(); you can call service function from here
},
getChats: function() {
console.log(this.chatData); // it will work here too
return this.chats;
},
getChat: function(chatId) {
for(i=0;i<this.chats.length;i++){
if(this.chats[i].id == chatId){
return this.chats[i];
}
}
}
}
});
Hope it will help you :) Thanks
I need to change the order of scope, save but me back an error that save() is not a function.
I'm using restangular to create the objects.
The function is triggered Onsort, I tried using http, but also gives me error.
$scope.onChange = function() {
ApiRestangular.all($scope.section).getList($scope.query).then(function(res){
$scope.items = res;
order = ApiRestangular.copy(res);
console.log(order);
$scope.sortOptions = {
animation : 150,
onSort: function(){
order.put().then(function(){
toast.msgToast($scope.section+ ' ...Ordem atualizada!');
});
}
};
});
};
I have installed the malhar-angular-dashboard module. I do not want to hard code my widgetDefinitions, so I created a service witch will return the array with the widget objects. I am using a rest service to return data such as the widget names, titles, etc. The problem is I get this error and do not know how to resolve :
TypeError: widgetDefs.map is not a function
SERVICE DATA
.factory('widgetRestService',['$http','UrlService','$log','$q',
function($http,UrlService,$log,$q){
var serviceInstance = {};
serviceInstance.getInfo = function(){
var request = $http({method: 'GET', url: '/rest/widgets/getListInfoDashboards'})
.then(function(success){
serviceInstance.widgets = success.data;
$log.debug('serviceInstance.widgets SUCCESS',serviceInstance.widgets);
},function(error){
$log.debug('Error ', error);
$log.debug('serviceInstance.widgets ERROR',serviceInstance.widgets);
});
return request;
};
serviceInstance.getAllWidgets = function () {
if (serviceInstance.widgets) {
return serviceInstance.widgets;
} else {
return [];
}
};
return serviceInstance;
}]);
widgetDefinitions service
.factory('widgetDefinitions',['widgetRestService','$log','$q','$http',function(widgetRestService,$log,$q,$http) {
var widgetDefinitions = [];
return widgetRestService.getInfo().then(function (data) {
var widgets = widgetRestService.getAllWidgets();
$log.debug('widgetsDefs ', widgets);
for (var i = 0; i < widgets.length; i++) {
widgetDefinitions.push(widgets[i]);
}
$log.debug('widgetDefinitions ', widgetDefinitions);
return widgetDefinitions;
});
});
Console
TypeError: widgetDefs.map is not a function
widgetDefs: [Object,Object,Object]
widgetDefinitions: [Object,Object,Object]
Note
If I hard-code my widgetDefinitions-service returned array like this it works, if I returned with my rest service doesn`t work(widgetDefs.map is not a function):
[
{
name:'widgetList',
title:'title1'
},
{
name:'widgetPie',
title:'title2'
},
{
name:'widgetTable',
title:'title3'
}
]
Original issue in github has been commented on and closed.
Here's the comment from github:
#pitong Make sure the dashboard options contains a property named widgetDefinitions and it's an array, even if it's empty. Also make sure the the browser version you're using supports the map function for arrays. This map function for array became the ECMA-262 standard in the 5th edition so your browser version might not have it supported.
I am building an SharePoint App using AngularJS and am attempting to define a service that retrieves if the user is an Admin or not. The service itself is successfully logging/working as expected, but I am not sure how to use this in a controller. My end goal is that when a page loads that is tied to a controller, that this service checks if they are an admin or not. From that point, I can do all sorts of magic (ex. redirect, etc.). Here is my service:
// Check if user is an admin
appServices.factory('appAdminCheck', ['$resource', 'appCurrentUserProfile', 'appAdmins', function ($resource, appCurrentUserProfile, appAdmins) {
var userAdmin = [];
appCurrentUserProfile.query(function (usercheck) {
var userID = usercheck.Id;
appAdmins.query(function (admins) {
var admins = admins.value; // Data is within an object of "value", so this pushes the server side array into the $scope array
// Foreach type, push values into types array
angular.forEach(admins, function (adminvalue, adminkey) {
if (adminvalue.Admin_x0020_NameId == userID) {
userAdmin = true;
console.log("I'm an Admin" + userAdmin);
}
});
});
});
return userAdmin;
}]);
Update: Upon closer inspection, I would like to return the array of values, but it keeps stating that the array length is 0. I am sure it is because I am not "returning" properly.
Here is my updated service:
appServices.factory('appAdminCheck', ['$resource', 'appCurrentUserProfile', 'appAdmins', function ($resource, appCurrentUserProfile, appAdmins) {
var userAdmin = [];
var checkUser = function() {
appCurrentUserProfile.query(function (usercheck) {
var userID = usercheck.Id;
appAdmins.query(function (admins) {
var admins = admins.value; // Data is within an object of "value", so this pushes the server side array into the $scope array
// Foreach type, push values into types array
angular.forEach(admins, function (adminvalue, adminkey) {
if (adminvalue.Admin_x0020_NameId == userID) {
userAdmin.push({
isAdmin: 'Yes',
role: adminvalue.Role,
});
}
});
});
});
return userAdmin;
}
return {
checkUser: checkUser
};
}]);
Here is a logging call in a controller:
var test = appAdminCheck.checkUser();
console.log(test);
Seeing as there appears to be some asynchronous actions happening, you'll want to return a promise. You can do this by chaining the then promise resolution callbacks from your other services (assuming they're $resource instances or similar). For example...
appServices.factory('appAdminCheck', function (appCurrentUserProfile, appAdmins) {
return function() {
return appCurrentUserProfile.query().$promise.then(function(usercheck) {
return appAdmins.query().$promise.then(function(admins) {
// this needs to change if admins.value is not an array
for (var i = 0, l = admins.value.length; i < l; i++) {
if (admins.value[i].Admin_x0020_NameId === usercheck.Id) {
return true;
}
}
return false;
});
});
};
});
Then, you can use this promise resolution in your controller, eg
appAdminCheck().then(function(isAdmin) {
// isAdmin is true or false
});
In app.js I have a variable that I use in two files/controllers:
var app = angular.module('appDemo', ['MainControllers', 'MainServices'])
.constant('myConfig', {
'backend': 'http://localhost:1236'
})
.service('mailService', function() {
var mail = {
value: 'hello world'
};
var getMail = function() {
return mail;
}
var setMail = function(email) {
mail.value = email;
}
return {
getMail: getMail,
setMail: setMail
};
);
Setting the variable from controllerOne goes fine:
angular.module('MainControllers')
.controller('MemberController', function ($scope, mainService, appDemo) {
window.onbeforeunload = function (e) {
appDemo.setMail('test#test.com');
};
But when I get the setting variable from the controllerTwo than I get the default value:
angular.module('MainControllers')
.controller('EmailController', function($scope, appDemo) {
$scope.mailAddress = appDemo.getMail();
});
Each controller is in separate file.
what is wrong?
This may be because the service itself is being reloaded because as I can see you are setting the mail in the first controller on onbeforeunload.
Services can't persist on window reloads or page refresh. They get reloaded hence reinitialized every time you reload the page.
If you want to persist the values try putting it in localStorage or sessionStorage.