get an undifined $scope in angularJS using api - angularjs

I'm new in angularJS and I got a small problem which is :
(i'll explain some details)
I have a SQL database which is deployed in Azure and I get the data from web services.
when I want to retrieve data from the database and expose it in the view , it works.
this is the controller :
var app = angular.module('ngdemoApp.controllers', []);
app.controller('CustomerViewCtrl', ['$scope', '$routeParams', 'ShowCustomerFactory','LikeProfilCustomerFactory','ShowManagerFactory',
function ($scope, $routeParams, ShowCustomerFactory,LikeProfilCustomerFactory,ShowManagerFactory) {
$scope.incrementLikeProfil = function (id) { LikeProfilCustomerFactory.likeProfil({id:$scope.customer.Id});
$scope.customer = ShowCustomerFactory.show({id: $routeParams.id});
}
$scope.customer = ShowCustomerFactory.show({id: $routeParams.id});
}]);
notice that the customer is in the database so it has properties in other word if I do {{customer.Id}} this expression shows me the value in the view.
However, when I want to use the $scope.customer in the controller like this
app.controller('CustomerViewCtrl', ['$scope', '$routeParams', 'ShowCustomerFactory','LikeProfilCustomerFactory','ShowManagerFactory',
function ($scope, $routeParams, ShowCustomerFactory,LikeProfilCustomerFactory,ShowManagerFactory) {
$scope.incrementLikeProfil = function (id) {
LikeProfilCustomerFactory.likeProfil({id:$scope.customer.Id});
$scope.customer = ShowCustomerFactory.show({id: $routeParams.id});
}
$scope.customer = ShowCustomerFactory.show({id: $routeParams.id});
$scope.test = $scope.customer.Id;
}]);
the $scope.test cannot be filled by $scope.customer.Id, at the same time the $scope.customer is filled and the view can display the value of customer but when I want to display the $scope.test in the view, i didn't get any responce.
Is there any solution ? Thank you

$scope.customer = ShowCustomerFactory.show({id: $routeParams.id});
If the above statement is making a service request and fetching data from server. This will be async and won't be available.
But in the next statement itself, you are setting
$scope.test = $scope.customer.Id;
At this point of time, $scope.customer may be undefined. That's why you're not getting the value.
You must put this statement in the then() function of promise $scope.test = $scope.customer.Id;
So in your service, return promise using $http or $q. And in your controller:
ShowCustomerFactory.show({id: $routeParams.id}).then(function(data) {
$scope.customer = data;
$scope.test = $scope.customer.id;
});
Another workaround would be :
Initially set
$scope.customer = {};

Also here is my service I use $resource :
services.factory('ShowCustomerFactory', function ($resource) {
return $resource(url + '/customerService/getCustomer?id=:id', {}, {
show: { method: 'GET',params: {id: '#id'} }
});
});

Related

nodejs, expressjs, angular, server-side controller fetching all data, but when called by angular controller, it is not returning anything

"findByStaff" and "findOne" are returning correct data, but "findAll" is not returning the data, I am expecting findAll should return all courses from mongodb
$scope.findByStaff = function() {
$scope.courses = Courses.query();
};
$scope.findAll = function() {
$scope.courses = Courses.query();
};
$scope.findOne = function() {
$scope.course = Courses.get({
courseId: $routeParams.courseId
});
};
These functions are in my controller which is looking like:
angular.module('courses').controller('CoursesController', ['$scope', '$routeParams', '$location', 'Authentication', 'Courses',
function($scope, $routeParams, $location, Authentication, Courses) {}
I think you are using $resources in your service Cources, have you tried to set up parameter isArray = true ?
isArray – {boolean=} – If true then the returned object for this
action is an array, see returns section.
https://docs.angularjs.org/api/ngResource/service/$resource

Angularjs cannot get data from service

I'm trying to pass data from one controller to another using a service, however no matter what I'm trying it always returns 'undefined' on the second controller. Here is my service :
app.service('myService', ['$rootScope', '$http', function ($rootScope, $http) {
var savedData = {}
this.setData = function (data) {
savedData = data;
console.log('Data saved !', savedData);
}
this.getData = function get() {
console.log('Data used !', savedData);
return this.savedData;
}
}]);
Here is controller1 :
.controller('HomeCtrl', ['$scope','$location','$firebaseSimpleLogin','myService','$cookies','$window', function($scope,$location, $firebaseSimpleLogin, myService, $cookies, $window) {
loginObj.$login('password', {
email: username,
password: password
})
.then(function(user) {
// Success callback
console.log('Authentication successful');
myService.setData(user);
console.log('myservice:', myService.getData()); // works fine
}]);
And then controller2:
// Dashboard controller
.controller('DashboardCtrl', ['$scope','$firebaseSimpleLogin','myService',function($scope,$firebaseSimpleLogin, $location, myService) {
console.log('myservice:', myService.getData()); //returns undefined
}]);
That is simple code, unfortunately I've been struggling for a few hours now, any suggestion ? Thanks.
Created a fiddle here:
http://jsfiddle.net/frishi/8yn3nhfw/16
To isolate the problem, can you remove the dependencies from the definition for myService and see if that makes it work? Look at the console after you load the fiddle.
var app = angular.module('app', [])
.service('myService', function(){
this.getData = function(){
return "got Data";
}
})
I assume the issue is that you are returning this.savedData in the service. Try returning savedData.
this behaves different in Javascript than in other languages.

AngularJS Data from a Service

So I have created a Notifications service in AngularJS and well I'm not getting any meaning full data back in my $scope.Notifications variable.
I can see the service is being called and running at the correct interval, and the correct data is being returned from the API:
[{"id":1,"user_id":1,"content":"You have new mail: Test","read":null,"type":"mail","deleted_at":null,"created_at":"2015-06-23 20:16:38","updated_at":"2015-06-23 20:16:38"},{"id":2,"user_id":1,"content":"You have new mail: Test","read":null,"type":"mail","deleted_at":null,"created_at":"2015-06-23 20:16:38","updated_at":"2015-06-23 20:16:38"},{"id":3,"user_id":1,"content":"You have new mail: Test","read":null,"type":"mail","deleted_at":null,"created_at":"2015-06-23 20:16:38","updated_at":"2015-06-23 20:16:38"}]
Essentially, all I need from this is a simple array of the users notifications.
Here is my service:
app.services.Notifications = ['$http', '$timeout', function($http, $timeout){
var timeoutId;
var notificationService = this;
function checkForNotifications(){
console.log('checking')
return $http.get('/api/notifications')
.then(function(res){
return res.data.filter(function(notification){
return notification.unread === true;
})
})
.then(function(unreadNotifications){
//fake for effect
notificationService.count = Math.floor(Math.random() * (100 - 1)) + 1;
//notificationService.count = unreadNotifications.length;
})
.then(waitAndCheck)
}
function waitAndCheck(){
return $timeout(function(){
checkForNotifications()
},5000);
}
return {
Notifications: waitAndCheck()
}
}];
And my controller:
app.controllers.notificationsController = ['$scope', 'Notifications', function($scope, Notifications) {
$scope.Notifications = Notifications;
}];
If I console log $scope.Notifications in the controller I being return this:
Object {Notifications: d}Notifications: d$$state: Objectstatus: 1value: undefined__proto__: Object$$timeoutId: 1__proto__: Object__proto__: Object
Set your $scope.Notifications = Notifications.Notifications;
app.controllers.notificationsController = ['$scope', 'Notifications', function($scope, Notifications) {
$scope.Notifications = Notifications.Notifications;
}];
Currently the thing which you are getting in console is nothing but a promise object which is conceptually correct. If you want the data from it then you use resolve that promise chain using .then function on Notification service.
Notifications.Notifications.then(function(data){
$scope.Notifications = data;
})

Angularjs data binding between controller and service

I'm not able to get the data binding between controller and service working.
I have a controller and a factory which makes an HTTP call. I would like to be able to call the factory method from other services and see the controller attributes get updated. I tried different options but none of them seem to be working. Any ideas would be greatly appreciated.
Please see the code here:
http://plnkr.co/edit/d3c16z?p=preview
Here is the javascript code.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
});
app.controller('EventDetailCtrl', ['$http', 'EventDetailSvc', '$scope',
function ($http, EventDetailSvc, $scope) {
this.event = EventDetailSvc.event;
EventDetailSvc.getEvent();
console.log(self.event);
$scope.$watch(angular.bind(this, function () {
console.log('under watch');
console.log(this.event);
return this.event;
}), function (newVal, oldVal) {
console.log('under watch2');
console.log(newVal);
this.event = newVal;
});
}])
.factory('EventDetailSvc', ['$http', function ($http) {
var event = {};
var factory = {};
factory.getEvent = function() {
$http.get('http://ip.jsontest.com')
.then(function (response) {
this.event = response.data;
console.log('http successful');
console.log(this.event);
return this.event;
}, function (errResponse) {
console.error("error while retrieving event");
})
};
factory.event = event;
return factory;
}]);
It seems to me that you have nested the event object inside of a factory object. You should be returning event directly instead wrapping it with factory. As it stands now you would need to call EventDetailSvc.factory.event to access your object.

Problems using $http inside a Service

I have a basic data Service which will be used across Controllers. But I'm having an issue grabbing some data that's been added via $http.
Service:
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
$http.get('/json').success(function(resp){
_this.dropdownData.industries = resp.industries;
});
}]);
Controller:
angular.module('core').controller('SignupController', ['$scope', '$http', '$state', 'FormService', function($scope, $http, $state, FormService) {
console.log(FormService.dropdownData); // Shows full object incl industries
console.log(FormService.dropdownData.industries); // empty object {}
}]);
How do I get FormService.dropdownData.industries in my controller?
Create a service like below
appService.factory('Service', function ($http) {
return {
getIndustries: function () {
return $http.get('/json').then(function (response) {
return response.data;
});
}
}
});
Call in controller
appCtrl.controller('personalMsgCtrl', ['$scope', 'Service', function ($scope, Service) {
$scope.Industries = Service.getIndustries();
}]);
Hope this will help
Add a method to your service and use $Http.get inside that like below
_this.getindustries = function (callback) {
return $http.get('/json').success(function(resp){
_this.dropdownData.industries = resp.industries;
callback(_this.dropdownData)
});
};
In your controller need to access it like below.
angular.module('core').controller('myController', ['$scope', 'FormService', function ($scope, FormService) {
FormService.getDropdownData(function (dropdownData) {
console.log(dropdownData); // Shows full object incl industries
console.log(dropdownData.industries); // object {}
});
} ]);
Given that your console log shows the correct object, that shows your service is functioning properly. Only one small mistake you have made here. You need to access the data attributes in your return promise.
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
$http.get('/json').success(function(resp){
//note that this is resp.data.industries, NOT resp.industries
_this.dropdownData.industries = resp.data.industries;
});
}]);
Assuming that you're data is indeed existing and there are no problems with the server, there are quite a few possible solutions
Returning a promise
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
_this.dropdownData.industries = $http.get('/json');
}]);
//Controller
FormService.industries
.then(function(res){
$scope.industries = res.industries
});
Resolving with routeProvider / ui-route
See: $http request before AngularJS app initialises?
You could also write a function to initialize the service when the application starts running. At the end of the day, it is about waiting for the data to be loaded by using a promise. If you never heard about promises before, inform yourself first.
The industries object will be populated at a later point in time when the $http call returns. In the meantime you can still bind to the reference in your view because you've preserved the reference using angular.copy. When the $http call returns, the view will automatically be updated.
It is also a good idea to allow users of your service to handle the event when the $http call returns. You can do this by saving the $promise object as a property of industries:
angular.module('core').service('FormService', ['$http', function($http) {
var _this = this;
_this.dropdownData = {
contactTimes: ['Anytime','Morning','Afternoon','Evening'],
industries: {},
};
_this.dropdownData.industries.$promise = $http.get('/json').then(function(resp){
// when the ansyc call returns, populate the object,
// but preserve the reference
angular.copy( resp.data.industries, _this.dropdownData.industries);
return _this.dropdownData.industries;
});
}]);
Controller
app.controller('ctrl', function($scope, FormService){
// you can bind this to the view, even though the $http call has not returned yet
// the view will update automatically since the reference was preserved
$scope.dropdownData = FormService.dropdownData;
// alternatively, you can hook into the $http call back through the $promise
FormService.dropdownData.industries.$promise.success(function(industries) {
console.log(industries);
});
});

Resources