I am currently working myself through tutorials and books teaching AngularJS.
I want to write a simple app, that loads some user data from a json file and displays it.
Now this is the relevant part of a JavaScript file, which does what I want:
Here is my Code :
angular.module('myModule', [])
.controller('myCtrl', function($scope, $http) {
$http.get('../mockdata/users_js.json').success(function(data, status, headers, config) {
$scope.users = data;
});
});
Now if I try to create a separate module for importing my data, I fail:
angular.module('myModule', [])
.controller('myCtrl', function($scope, Users) {
$scope.users = Users.query();
})
.factory('Users', function($http) {
var users = {};
users.query = function() {
// In real apps, we'd pull this data from the server...
$http.get('../mockdata/users_js.json').success(function(data, status, headers, config) {
this.data = data;
});
return this.data;
};
return users;
});
What am I doing wrong ?
And How can i fix this ?
In users.query() you kick off an asynchronous HTTP request, and then before it has a chance to finish return this.data which is undefined.
You could take a look at $resource, it returns a promise that you can assign to a $scope variable immediately. It will apply the right value when the request completes.
.factory('Users', function($resource) {
var users = {};
users.query = function() {
return $resource('../mockdata/users_js.json').get();
};
return users;
});
If you want to know how to do this with $http:
angular.module('myModule', [])
.controller('myCtrl', function($scope, Users) {
Users.then(function(data){
$scope.users = data;
});
})
.factory('Users', function($http) {
var Users = {};
Users = $http.get('../mockdata/users_js.json').then(function (response) {
return response.data;
});
return Users;
});
Here's a live Plnkr.
Related
Hi I am developing my first Angularjs application. I want to save data in Angularjs application for later use(I have used localstorage in jquery before).
For example, I will make ajax call and i will get some data, Lets say below example,
$http.post('http://192.168.0.213:1234/api/VerifyUser', $stateParams.pageList).then(function (response) {
alert(response.data);
another example, After succesfull login i will get some ID in response and i want to preserve this data all over the application. This ID i may use in all subsequent ajax calls.
I will get some data in response and i want to make use that data in other controllers as well. Is there any way i can do this? any help would be appreciated. Thank you.
you can store it in factory like below,
After your Ajax call
$http.post('http://192.168.0.213:1234/api/VerifyUser', $stateParams.pageList).then(function (response) {
alert(response.data)
SomeFactory.setData(response.data);
};
SomeFactory
(function () {
'use strict';
angular
.module('app.myApp')
.factory('SomeFactory', SomeFactory);
SomeFactory.$inject = [];
function SomeFactory() {
var someData;
var factory = {
setData: setData,
getData: getData
};
function setData(data) {
someData = data;
}
function getData() {
return someData;
}
return factory;
}
})();
In your Controllers
inject your factory to your controller and then getdata
(function () {
'use strict';
angular
.module('app.login')
.controller('LoginController', LoginController);
LoginController.$inject = ['SomeFactory'];
function LoginController(SomeFactory) {
var vm = this;
vm.someVariable = SomeFactory.getData();
console.log(vm.someVariable); // logs your data
}
})();
Sharing data between controllers can be achieved with the following options :
Factory
Service
Then you can inject the service across the controllers and use the data whenever you need.
app.service('myService', function($http) {
this.getJSON = function() {
$http.post('http://192.168.0.213:1234/api/VerifyUser', $stateParams.pageList).then(function(response) {
return response.data;
});
};
});
In Controller:
app.controller('myController', function($scope, myService) {
myService.getJSON().then(function(data) {
$scope.myData = data;
console.log(data);
});
});
DEMO
Use Service to store the data and get the data in another controller later on.
When you inject a Service, it's the same service in every controller - so you can access the properties and methods in that service all over.
https://docs.angularjs.org/guide/services
Example:
.service('YourService', function(){
var YourService = {};
YourService.yourvar = '';
return YourService;
})
.controller('controller1', function($scope, YourService){
YourService.yourvar = 'blah';
})
.controller('controller2', function($scope, YourService){
$scope.currentYourVar = YourService.yourvar;
})
This is more of a writing clean code/ optimizing existing code.
I am writing my Angular Services to fetch data from backend like this
angular.module('myApp').service('Auth', ['$http', '$q', 'Config', function($http, $q, Config) {
this.getUser = function() {
return $http.get(Config.apiurl + '/auth/user')
.then(function(response) {
return response.data;
}, function(error) {
return $q.reject(error.data);
});
};
}]);
Now in this, I am calling getUser function n number of times from the Database.
Now the question is, is it okay to call this service to get n times redundant data or I should it be saved somewhere say rootscope to be accessed later? Or storing in root scope would be bad practice and I should consider some other option or nothing at all?
Would like to get some views on Angular Community here.
Here is a sample example on how to use factory for sharing data across the application.
Lets create a factory which can be used in entire application across all controllers to store data and access them.
Advantages with factory is you can create objects in it and intialise them any where in the controllers or we can set the defult values by intialising them in the factory itself.
Factory
app.factory('SharedData',['$http','$rootScope',function($http,$rootScope){
var SharedData = {}; // create factory object...
SharedData.appName ='My App';
return SharedData;
}]);
Service
app.service('Auth', ['$http', '$q', 'SharedData', function($http, $q,SharedData) {
this.getUser = function() {
return $http.get('user.json')
.then(function(response) {
this.user = response.data;
SharedData.userData = this.user; // inject in the service and create a object in factory ob ject to store user data..
return response.data;
}, function(error) {
return $q.reject(error.data);
});
};
}]);
Controller
var app = angular.module("app", []);
app.controller("testController", ["$scope",'SharedData','Auth',
function($scope,SharedData,Auth) {
$scope.user ={};
// do a service call via service and check the shared data which is factory object ...
var user = Auth.getUser().then(function(res){
console.log(SharedData);
$scope.user = SharedData.userData;// assigning to scope.
});
}]);
In HTML
<body ng-app='app'>
<div class="media-list" ng-controller="testController">
<pre> {{user | json}}</pre>
</div>
</body>
Instead of rootScope just use a local variable of user in your service that can be accessed from anywhere in your code and so you doesn't have to call the api every time.
angular.module('metaiotAdmin').service('Auth', ['$http', '$q', 'Config', function($http, $q, Config) {
this.getUser = function() {
if(this.user){
return this.user;
}
else{
return $http.get(Config.apiurl + '/auth/user')
.then(function(response) {
this.user = response.data;
return response.data;
}, function(error) {
return $q.reject(error.data);
});
}
};
}]);
Hope it helps.
You don't have to, $http already caches your request for you, if the same request is applied in case you set the cache config option to true.
$http.get('/hello', { cache: true})
.then(onResponse)
or you can either set it for every request, by using either an interceptor or override the http instance in the $httpProvider, to apply the effect for every http request.
app.module('app.module')
factory('MyHttpInterceptor', function() {
return {
request : function(config) {
config.cache = true;
return config;
},
// rest of implementation of the interceptor
}
});
app.module('app.module')
.config(['$httpProvider', function($httpProvider) {
$httpProvider.interceptors.push('MyHttpInterceptor');
// ... rest of the configuration
}]);
Or :
app.module('app.module')
.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.cache = true;
// ...
}]);
see :
Angular doc for caching
i have used Angularjs and i wanna call getcustomer function from one controller to another controller i have so many doing gooogling but i don't have an idea that how to call that
i have write below code which i used
var app = angular.module('Napp', []);
app.controller('GetAlphabetical', function ($scope, $http) {
function getCutomers() {
$scope.loading = true;
$http.get('#Url.Content("~/Home/GetPesrons")').then(function (response) {
//var _data = angular.fromJson(response);
$scope.loading = false;
$scope.Customer = response.data; // please check the request response if list id in data object
}, function (error) {
throw error;
})
}
});
and second controller :
app.controller('MainCtrl', function ($scope, $http) {
getCutomers()
});
Mate, you will have to follow the following steps to resolve your problem. Firstly you have you create a factory
angular
.module('Napp')
.factory('CustomerFactory', ['$http', function ($http) {
var _factory = {};
_factory.getCustomers = function () {
return $http.get('#Url.Content("~/Home/GetPesrons")');
};
return _factory;
}]);
Then you can share data and functions between multiple controllers or services
GetAlphabetical Controller :
angular
.module('Napp')
.controller('GetAlphabetical', ['$scope', 'CustomerFactory', function ($scope, CustomerFactory) {
loadCustomers();
function loadCustomers() {
CustomerFactory.getCustomers().then(function (successResponse) {
$scope.Customer = successResponse.data; // please check the request response if list id in data object
}, function (errorResponse) {
throw error;
})
}
}]);
MainCtrl Controller :
angular
.module('Napp')
.controller('MainCtrl', ['$scope', 'CustomerFactory', function ($scope, CustomerFactory) {
loadCustomers();
function loadCustomers() {
CustomerFactory.getCustomers().then(function (successResponse) {
$scope.Customer = successResponse.data; // please check the request response if list id in data object
}, function (errorResponse) {
throw error;
})
}
}]);
This can be easily done by defining it as a service and injecting it as a dependency.
var app = angular.module('myApp', []);
myApp.service('helloWorldFromService', function() {
this.sayHello = function() {
return "Hello, World!"
};
});
app.controller('MainCtrl', function ($scope, $http, helloWorldFromService) {
app.controller('GetAlphabetical', function ($scope, $http, helloWorldFromService) {
Angular Service
What you want to do is to somehow communicate between two controllers. This can be easily be achieved using $broadcast & $on.
Incase there is a parent child relation between your controllers, use the following.
function firstCtrl($scope){
$scope.$broadcast('someEvent', [1,2,3]);
}
function secondCtrl($scope){
$scope.$on('someEvent', function(event, mass) {console.log(mass)});
}
If there is no parent child relationship between your controller, then inject $rootScope and broadcast using that.
related question - https://stackoverflow.com/a/14502755/1182982
Can someone crate an example of how I could set a $scope variable from a outside the controller using a factory or service that uses AJAX?
Every time I have tried the AJAX variable returns undefined because the request has not returned yet, so $scope.var is undefined. After the AJAX request returns, $scope.var is still undefined even if I call the service from the Controller. Please help.
Please see demo here http://plnkr.co/edit/JcRY8uHRYaHH33UTH7Bt?p=preview
var app = angular.module("myapp", []);
app.service("dataService", function($http, $q) {
var data = [];
function getData() {
var deffered = $q.defer();
var request = {
url: 'data.json',
method: 'GET'
};
$http(request).then(sucess, error);
function sucess(response) {
deffered.resolve(response.data);
}
function error() {
deffered.reject();
}
return deffered.promise;
}
return {
data: data,
getData: getData
}
})
app.controller('MyControl', function($scope, dataService) {
$scope.data = [];
dataService.getData().then(function(response) {
$scope.data = response;
})
});
I am trying to create factory for the restful services.
I need to make service calls. First call's data will be used to get the second calls data.
My problem is I don't know how to transfer data from one controller to another controller.
Is there a better way to do my codes?
Here are my codes...
var app = angular.module('myApp', []);
//getting init data via service
app.factory('myService', function($http) {
var myService = {
async: function() {
var promise = $http.get('test/test.json').then(function (response) {
return response.data;
});
return promise;
}
};
return myService;
});
//retrieve data
app.controller('testCtrl', function(myService, $scope, $http) {
myService.async().then(function(data) {
$scope.data = data
//using retrieve data to get another piece of data
vay first = data[0].employee[0];
})
$http({
url: "test?" + first +'.json',
method: "GET",
}).success(function(secondData) {
$scope.secondData=secondData //How do I pass data to my secondCtrl?
})
})
app.controller('secondCtrl', function($scope) {
// I need to be able to get the secondData from testCtrl.
console.log($scope.secondData)
})
Thanks for the help!
Why don't you store the data as an object in the service itself, then both controllers depend on the service and have access to the data. Like this:
app.factory('myService', function($http) {
var that = this;
var myService = function($http) {
this.set = function(url) {
var promise = $http.get(url).then(function (response) {
that.data = promise.data;
});
return promise;
}
};
return new myService($http);
});
Then your controller sets and gets the data in the way
app.controller('testCtrl', function(myService, $scope, $http) {
myService.set('someurl').then(function() {
$scope.data = myservice.data;
//using retrieve data to get another piece of data
vay first = data[0].employee[0];
myservice.set('someOtherUrl?data='+first);
})
app.controller('secondCtrl', function($scope, myservice) {
//the data object on the myservice function has been changed on the first controller and we can reasonably expect the data we need. If these 2 controllers coexist in the same space and time we can wrap this in a $watch service
console.log(myservice.data)
});
$watch service example
app.controller('secondCtrl', function($scope, $watch, myservice) {
$watch('myservice.data', function(newval, oldval) {
console.log(newval);
}, true)
//I will only log the newvalue of myservice.data when the data has changed. the last true argument is a neccesity so that angular will compare the values within the object
});
You could either extend 'myService' to contain the response data, using it in both controllers, or you could create another service for sharing data between them.
Both solutions would look similar, but here is what the second option (new service) might look like:
Factory
.factory('SharedService', function(){
var shared = {
data: ''
}
return shared;
})
This factory could act as just a place to store some data. In fact, if all you'd like to do is share data, you could just use a value provider. But a factory you could later extend with a more complex data structure and methods.
In your controllers, just inject the service and, optionally, set it to a scope variable:
Controller 1
.controller('FirstController', function($scope, SharedService){
$scope.shared = SharedService;
$scope.shared.data = 'foo';
})
$scope.shared now references the service object. If you were to do the same in the other controller, they could both read/write to that same object:
Controller 2
.controller('SecondController', function($scope, SharedService){
$scope.shared = SharedService;
console.log($scope.shared.data); // 'foo' if called after first ctrl set it
})
Demo