I am very new to angularjs and am having a hard time trying to figure out this issue.
Basically, we are using a factory to request data for our application. When the factory returns a promise, we were hoping that the data inside the returned promise that was defined in our scope, would be able to be used, but it is only returning as text on the page.
For example: We have defined $scope.name in our controller:
app.controller('AccountController',function($scope,Account) {
$scope.name = 'Abby';
$scope.news = [];
Account.getSnapshot().success(function(data) {
$scope.news.push(data);
});
});
so the factory (getSnapshot) will return something like "Hello {{name}}" from an $http request as follows:
app.factory('Account',function($http) {
return {
getSnapshot : function() {
return $http.get('data.php');
}
}
});
Is it possible to allow the factory to access /use {{name}} from the $scope?
You will need to use internal Angular $interpolate service:
app.controller('AccountController', function($scope, $interpolate, Account) {
$scope.name = 'Abby';
$scope.news = [];
Account.getSnapshot().success(function(data) {
var text = $interpolate(data)($scope);
$scope.news.push(text);
});
});
Use $q and promises thanks to #dfsq's answer on my post similar to this. Works perfectly.
Here's a plunker.
// Factory method.
app.factory('Account', function($http, $q) {
var data;
return {
getSnapshot: function() {
return data ? $q.when(data) : $http.get('data.json').then(function(response) {
data = response.data;
return data;
})
}
}
});
// Controller method.
app.controller('AccountController', function($scope, Account) {
$scope.name = 'Abby';
$scope.news = [];
Account.getSnapshot().then(function(data) {
$scope.news = data;
});
});
Related
I have code:
angular.module('admin', [])
.provider('users', function () {
this.users = 'default';
this.$get = function () {
var that = this;
return {
getUsers: function () {
return that.users;
}
}
};
})
.run(function (users, $http) {
users.users = $http('url'); // and others
})
.controller('test', function ($scope, users) {
$scope.users = users.getUsers();
});
I would like to intitalize data in .run() method (I can't use .config() method because it doesn't let to pass any services like $http). I found .run() method, but this code doesn't work... Data aren't saved in provider. Official documentation says:
"Execute this function after injector creation. Useful for application initialization."
I think it's best way to initialize data.
You may want to use an Angular Factory/Service for this kind of need. That is what I do. And pass that into the application. That service will be your singleton or source of truth about the dat.
angular.module('myData.services', [])
.factory('myData', ['$rootScope', '$http' , function($rootScope,$http) {
var factory = {
myData : {}
};
$http('/api/call', function(apiData) {
factory.myData = apiData;
});
return factory;
}]);
You could then use this in your controllers:
angular.module('myApp.controllers', [])
.controller('myCtrl', ['myData', '$scope', function(myData, $scope){
$scope.users = myData;
}]);
Check out the documentation on services: https://docs.angularjs.org/guide/services
Second attempt
angular.module('admin', [])
.factory('users', function ($http) {
var users = {};
var data = [];
$http.get('database.php')
.then(function (response) {
data = response.data;
});
users.getData = function () {
return data;
};
return users;
})
.controller('test', function ($scope, users) {
console.log(users.getData());
});
I would like to have data private. Empty Array returned, reponse comes with all data.
Provider configuration can be doable inside config block only, you can't do that inside run block
Though I don't find a reason to load users object while configuring app. I'd say that you should use either service/factory for this.
Code
angular.module('admin', [])
.service('users', function($http, $q) {
var users = [];
//make an get call to fetch users
function getUsers() {
return $http.get('database.php')
.then(function(response) {
data = response.data;
});
}
//will make a call if users aren't there
this.getData = function() {
// Handled below two conditions
// 1. If users aren't fetched the do an Ajax
// 2. If last ajax doesn't return a data then DO it again..
if (users.length > 0)
return $q.resolve(data); //do return data using dummy promise
return getUsers();
};
return users;
})
.controller('test', function($scope, users) {
users.getData().then(function(data){
console.log(data);
});
});
I created a service that fetches data from local json and use it in a controller to display it in browser. All are working fine. here is my code:
JS Code:
var myApp = angular.module("myApp", ['ngRoute']);
myApp.service("dataService", function($http, $q){
var deferred = $q.defer();
$http.get('json/link.json').then(function(data){
deferred.resolve(data);
});
this.getData = function(){
return deferred.promise;
}
})
.controller("linkCtrl", function($scope, dataService) {
var promise = dataService.getData();
promise.then(function(data) {
$scope.links = data.data;
});
});
Now, i have another json link (for eg.: json/link2.json ) and i want to perform the same function. Is there any way to use the "dataService" service ( like changing the link ).
I don't want to re-create a new service which does the same function. Any idea to re-use the Service for different json data ?
Thanks in Advance
Just create a method you can pass url to:
myApp.service("dataService", function($http){
this.getData = function(url){
return $http.get(url); // this returns a promise
};
})
Use it like this:
.controller("linkCtrl", function($scope, dataService) {
var promise1 = dataService.getData('json/link.json');
promise1.then(function(data) {
$scope.links = data.data;
});
var promise2 = dataService.getData('json/link2.json');
promise2.then(function(data) {
$scope.links2 = data.data;
});
});
Try something like this
myApp.service("dataService", function($http){
this.getData = function(link,callback){
$http.get(link).then(function(data){
if(callback)
callback(data);
});
});
myApp.controller("linkCtrl", function($scope, dataService) {
dataService.getData('json/link.json', function(data){
$scope.links = data.data;
});
});
I'm working on a mobile app using AngularJS as a framework, currently I have a structure similar to this:
app.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl : 'pages/home.html',
controller : 'homeCtrl'
})
.when('/one', {
templateUrl : 'pages/one.html',
controller : 'oneCtrl'
})
.when('/two', {
templateUrl : 'pages/two.html',
controller : 'twoCtrl'
});
}]);
app.controller('homeCtrl', ['$scope', function($scope) {
}]);
app.controller('oneCtrl', ['$scope', function($scope) {
}]);
app.controller('twoCtrl', ['$scope', function($scope) {
}]);
And then I'm displaying the content with an ng-view:
<div class="ng-view></div>
Things are working well but I need to load data from a JSON file to populate all the content of the app. What I want is to make and an AJAX call only once and then pass the data through all my different controllers. In my first attempt, I thought to create a Service with an $http.get() inside of it and include that in every controller, but it does not work because it makes a different ajax request everytime I inject and use the service. Since I'm new using angular I'm wondering what is the best way or the more "angular way" to achieve this without messing it up.
Edit: I'm adding the code of the service, which is just a simple $http.get request:
app.service('Data', ['$http', function($http) {
this.get = function() {
$http.get('data.json')
.success(function(result) {
return result;
})
}
});
Initialize the promise once, and return a reference to it:
No need to initialize another promise. $http returns one.
Just tack a .then() call on your promise to modify the result
angular.module('app', [])
.service('service', function($http){
this.promise = null;
function makeRequest() {
return $http.get('http://jsonplaceholder.typicode.com/posts/1')
.then(function(resp){
return resp.data;
});
}
this.getPromise = function(update){
if (update || !this.promise) {
this.promise = makeRequest();
}
return this.promise;
}
})
Codepen example
Edit: you may consider using $http cache instead. It can achieve the same results. From the docs:
If multiple identical requests are made using the same cache, which is not yet populated, one request will be made to the server and remaining requests will return the same response.
Try this to get JSON Data from a GET Link:
(function (app) {
'use strict';
app.factory('myService', MyService);
MyService.$inject = ['$q', '$http'];
function MyService($q, $http) {
var data;
var service = {
getData: getData
};
return service;
//////////////////////////////////////
function getData(refresh) {
if (refresh || !data) {
return $http.get('your_source').then(function(data){
this.data = data;
return data;
})
}
else {
var deferrer = $q.defer();
deferrer.resolve(data);
return deferrer.promise;
}
}
}
}(angular.module('app')));
Now you can add this dependency in your controller file and use:
myService.getData().then(function(data){
//use data here
}, function(err){
//Handle error here
});
I can see my json data in the console and I want to view it on html page after clickbutton function. From my understaning I can either do a promise ($q) or then with http or ngResource. First I want to do http then migrate to ngResource. For some reason my scope is still undefined. Maybe it's a ng-init or ng-repeat I'm missing? Any ideas?
var app = angular.module('myApp', []);
app.factory('httpq', function($http, $q) {
return {
get: function() {
var deferred = $q.defer();
$http.get.apply(null, arguments)
.success(deferred.resolve)
.error(deferred.resolve);
return deferred.promise;
}
}
});
app.controller('myController', function($scope, httpq) {
httpq.get('http://localhost:8080/states')
.then(function(data) {
$scope.returnedData = data;
})
$scope.clickButton = function() {
$scope.returnedData;
}
});
view
<div data-ng-controller="myController">
<button data-ng-click="clickButton()">Get Data From Server</button>
<p>JSON Data : {{returnedData}}</p>
</div>
Use Ajax call
Service:
var demoService = angular.module('demoService', [])
.service('myService',['$http', function($http) {
this.getdata = function(entity){
var promise = $http({
method : 'POST',
url : 'services/entity/add',
data : entity,
headers : {
'Content-Type' : 'application/json'
},
cache : false
}).then(function (response) {
return response;
});
return promise;
};
}]);
Controller :
var demoService = angular.module('demoService', [])
.controller('myctr',['$scope','myService',function($scope,myService){
myService.getdata().then(function(response){
//Success
},function(response){
//Error
});
}]);
now you can see your json in controller success
$http itself is a promise, no need to create a new promise. Just return the $http.get wihoit the success written there and right the sucess fn in the controller itself. So your code will look like this:
app.factory('httpq', function($http) {
return {
get: function() {
return $http.get.apply(null, arguments);
}
}
});
Your controller:
app.controller('myController', function($scope, httpq) {
httpq.get('http://localhost:8080/states').then(function(data) {
$scope.returnedData = data;
})
$scope.clickButton = function() {
$scope.returnedData;
}
});
use
$scope.returnedData=JSON.parse(data);
It will give you values in JSON format
I have not worked with promise. But your factory code seems to be ok.
In controller declare your object first.
If it's just object declare it as
$scope.returnedData = {};
If it's array, declare it as
$scope.returnedData = [];
The the object will not be undefined and changes will affect in HTML
I am new to learning angular and having trouble understand some of the basics.
I have my controller line shown below:
$scope.test = fileLoader.loadFile();
And my factory service shown below:
angular.module('myWellnessTrackerApp')
.factory('fileLoader', function($http) {
return{
loadfile : function(fileLoc){
$http.get('data/sideEffects.json').success(function(data) {
// you can do some processing here
return data;
});
}
};
});
Which throws an error. But when my controller line is
$scope.test = fileLoader.data;
And my service is
angular.module('myWellnessTrackerApp')
.factory('fileLoader', function($http) {
var obj = {content:null};
$http.get('data/sideEffects.json').success(function(data) {
// you can do some processing here
obj.content = data;
});
return obj;
});
Which i don't understand and I would like to be able to understand how to make services in particularly a HTTP service wrapper for requesting a page or local file and having it returned.
Thanks
You can't just do
$scope.test = fileLoader.loadFile();
loadFile is an async call, and you can't return from that! You can use .then to continue the promise pattern. Your factory would change to:
loadFile : function(fileLoc){
return $http.get('data/sideEffects.json').then(function(result) {
// you can do some processing here
return result.data;
});
}
And your controller:
fileLoader.loadFile().then(function(data) {
$scope.test = data;
});