I am trying to parse in my HTML page many JSON files:
Here is my service's code:
app.factory('myapp', ['$http', function($http) {
var tab = ['url1', 'url2', 'url3']
for(i=0; i<tab.length; i++){
return $http.get(tab[i])
.success(function(data) {
return data;
})
.error(function(err) {
return err;
}); }
}]);
In my HTML file , I only have the information of the first json file.
Here's my HTML code:
<tr>
<td>{{data.nm}}</td>
<td>{{data.cty}}</td>
<td>{{data.hse}}</td>
<td>{{data.yrs}}</td>
</tr>
Is there something to add in my HTML so I can get the information from all the json files or any other solution?
First off, you return in the first iteration in your for loop, so you only get the data for the first url. Don't return right away, assign a scope variable to your data:
Factory
app.factory('myapp', ['$http', function($http) {
function getLists() {
var tab = ['url1', 'url2', 'url3'];
var list = [];
for(i=0; i<tab.length; i++){
$http.get(tab[i])
.then(function(res) {
list.push(res.data);
});
}
return list;
}
return {
getLists: getLists
};
]);
Controller
$scope.list = myapp.getLists();
HTML
<tr ng-repeat="d in list">
<td>{{d.nm}}</td>
<td>{{d.cty}}</td>
<td>{{d.hse}}</td>
<td>{{d.yrs}}</td>
</tr>
I think what you are looking for is $q.all
I would solve the problem like this
angular.module('app').factory('myRequestsFactory',function($http, apiHost) {
var myRequestsFactory = {};
myRequestsFactory.geturl1 = function() {
return $http.get(url1);
};
myRequestsFactory.geturl2 = function() {
return $http.get(url2);
};
myRequestsFactory.geturl3 = function() {
return $http.get(url3);
};
return myRequestsFactory;
});
Then I would create an other service
angular.module('app').factory('helperService',function($q, myRequestsFactory) {
var helperService = {};
helperService.GetAll = function() {
return $q.all([
myRequestsFactory.geturl1(),
myRequestsFactory.geturl2(),
myRequestsFactory.geturl3() ]);
};
return helperService;
});
Then in my controller ..
function loadData() {
helperService.GetAll().then(
function(result) {
$scope.url1result = result[0];
$scope.url2result = result[1];
$scope.url3result = result[2];
});
},
function(error) {
}
);
}
That's how i would get access to this data
Related
I'm trying get data from db to UI. Url given via provider is getting the data.
Controller in controller DetailsProvider.getDashboardDetails() is getting null.
var appmod = angular.module('project.DetailDashboardController', []);
appmod.controller("DetailDashboardController", ['$rootScope', '$scope', '$state', 'DetailsProvider',function($rootScope, $scope, $state,DetailsProvider) {
console.log("DetailDashboardController --- ");
$scope.DetList= DetailsProvider.getDashboardDetails()
}]);
})(window, window.angular);
provider which will call the list
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
Thanks in advance for any kind of reply!
You should return promise from your service method and do thenable in your controller.
Root Cause : your are returning the newData which will initalized later after completing the ajax call.Before completing it,you are returning the same variable which will be always null.
In provider,
(function(angular) {
var appmod = angular.module('project.DetailsServiceProvider', []);
appmod.provider('DetailsProvider', function() {
this.$get = ['_$rest', function DetailServiceFactory(_$rest) {
return new DetailsProvider(_$rest);
}];
});
function DetailsProvider(_$rest) {
this._$rest = _$rest,
this.getDashboardDetails = function(_callback, _data) {
var newData = null;
_$rest.post({
url: window.localStorage.getItem('contextPath') +'home/listdetail',
data: {} ,
onSuccess:_callback
}
});
}
};
})(window.angular);
and in controller,
$scope.list = function() {
DetailsService.getDashboardDetails(function(data){
varr holdIt = data.data.DList;
});
};
I am working on an application in which I am calling a webservice and get a response. I am using that response in 2 different modules. In first module I am using as it is and in second module I am doing some formatting and using it.
I created a service for getting data as follows
angular.module('myApp').factory('getData',function($http, $q, restURLS) {
var getData= {};
getData.getTree = function () {
var deferred = $q.defer();
$http.get(restURLS.getTree).
success(function (data) {
deferred.resolve(data);
}).error(deferred.reject);
return deferred.promise;
};
return getData;
});
for Serving response I created another factory as follows
angular.module('myApp').factory('tree', function($http, $q, restURLS, getData, messages) {
var tree= {};
tree.hierarchy = {};
tree.formattedHierarchy = {};
function formatHierarchy(data) {
//some formatting on data.
tree.formattedHierarchy = data;
}
function callTree() {
getData.getTree()
.then(function (data) {
tree.hierarchy = angular.copy(data);
formatHierarchy(data);
}).catch(function () {
//error
});
}
callTree();
return tree;
});
I want to call webservice only once. if data is loaded then factory('tree') should send the data to controller. Otherwise factory('tree') should call webservice and load data.
you need something to know if you got your tree or not... try this:
(UPDATED)
var myApp = angular.module('myApp', ['ngMockE2E'])
// FAKE HTTP CALL JUST FOR EMULATE
.run(function ($httpBackend) {
var tree = [{
node1: 'abcde'
}, {
node2: 'fghi'
}];
$httpBackend.whenGET('/tree').respond(function (method, url, data) {
return [200, tree, {}];
});
})
// YOUR HTTP SERVICE
.factory('getData', function ($http, $q) {
return {
getTree: function () {
var deferred = $q.defer();
$http.get("/tree").
success(function (data) {
deferred.resolve(data);
}).error(deferred.reject);
return deferred.promise;
}
}
})
.factory('TreeFactory', function ($http, $q, getData) {
var tree = {};
var updated = false;
tree.hierarchy = {};
tree.formattedHierarchy = {};
function formatHierarchy(data) {
//some formatting on data.
tree.formattedHierarchy = data;
}
return {
callTree: function() {
if(!updated){
console.log("making http call");
return getData.getTree().then(function (data) {
tree.hierarchy = angular.copy(data);
formatHierarchy(data);
updated = true;
return tree;
}).
catch (function () {
//error
});
}else{
console.log("tree already loaded");
var deferred = $q.defer();
deferred.resolve(tree);
return deferred.promise;
}
}
};
}).controller("MyCtrl", ['$scope', 'TreeFactory', function ($scope, TreeFactory) {
$scope.updateTree = function(){
TreeFactory.callTree().then(function(data){
$scope.tree = data;
});
};
}]);
HTML
<div ng-app="myApp" ng-controller="MyCtrl" ng-init="updateTree()">tree: {{tree}} <br><button ng-click="updateTree()">UPDATE TREE</button></div>
CHECK THE FIDDLE
How to load info of a function and save it in scope from resolve in a route using AngularJS?
For example:
.state('list.employee_list', {
url: "/employee_list",
templateUrl: "views/list/employee_list.html",
data: { pageTitle: 'Employee list' },
resolve: {
"employeesCollection" : function(){
alert("LOAD");
$scope.myData = myFunction($scope);
alert("finished load, now load view");
}
}
})
The idea is to load info of a table before loading its view, so the table won't be empty. The function gets the data from Parse.com
EDIT:
config.js
.state('list.employee_list', {
url: "/employee_list",
templateUrl: "views/list/employee_list.html",
data: { pageTitle: 'Employee list' },
controller: employeeListCtrl,
resolve: {
employeesCollection : employeeListCtrl.loadData(companyID)
}
})
controllers.js
function employeeListCtrl($scope, employeesCollection){
$scope.employeesCollection = employeesCollection;
}
employeeListCtrl.loadData = function(companyID){
var employeesCollection = [];
var User = Parse.Object.extend("User");
var promise = new Parse.Promise();
var query = new Parse.Query(User);
query.equalTo("companyID", companyID);
query.find().then(function(results) {
for (var i = 0; i < results.length; i++) {
var estado = results[i].get("sendTest");
if(estado == "no"){
results[i].status = "{{ 'FREE' | translate }}";
}else if(estado == "yes"){
results[i].status = "{{ 'TEST_SENT' | translate }}";
}
console.log(results[i].get("lastName"));
employeesCollection[i] = results[i];
}
}).then(function(redirect) {
// Everything is done!
//window.location.href = "#/list/employee_list";
promise.resolve();
console.log("LOADED");
return employeesCollection;
});
}
views/list/employee_list.html
<tr ng-repeat="row in employeesCollection">
<td>
{{row.get("firstName")}}
</td>
<td>
{{row.get("lastName")}}
</td>
<span class="label label-primary">{{status}}</span>
</td>
</tr>
Here's how you can accomplish it:
First, create a service to get your data. Let's say you have a simple service called MyData:
app.factory('MyData', ['$http', function ($http) {
var obj = {};
obj.get = function (myendpoint) {
return $http.get('https://some/endpoint/to/get/data/'+myendpoint).then(function (results) {
return results.data;
});
};
return obj;
}]);
Now you can pass that service to the resolve function in your $routeProvider:
.when('/events', {
templateUrl: 'views/events.html',
controller: 'EventsCtrl',
resolve: {
preloaded: function(MyData) {
return MyData.get('allevents');
}
}
})
And, in your controller, you can pass the resolve object to gain access to your data:
app.controller('EventsCtrl', ['$scope', 'preloaded', function ($scope, preloaded) {
$scope.allevents = preloaded;
}]);
Seems like you should just load the view, and call your method to get the data from Parse inside your controller.
When you've got the data, just call $scope.$apply() to update the bindings, and your table should update. This is probably best practice, and it will allow you to show some sort of loading animation on the table.
I have an angular filter set up which works great:
categorieFilter = angular.module("categorieFilter", [])
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.categories = store.getCategories();
$scope.products = store.getProducts();
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
categorieFilter.factory('store', function(){
var categories = ['Lattes','CC Blend','Frappes'];
var products = [
{name: 'Latte machiatto',category: 'Lattes'},
{name: 'Frappe ice',category: 'Frappes'},
{name: 'Latte caramel',category: 'Lattes'},
{name: 'Frappe speculoos',category: 'Frappes'},
{name: 'Cappucino',category: 'CC Blend'},
{name: 'Filter coffee',category: 'CC Blend'},
];
return {
getCategories : function(){
return categories;
},
getProducts : function(){
return products;
}
};
});
But the var categories and var products are still hard coded so I want to retreive the needed data from my server to fill these variables. And I can't seem to get this right? I have another function where I can get the required data but I don't know how I can get these 2 in 1...?
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
$scope.categories = results.data;
for(var i = 0; i < $scope.categories.length; i++){
var categories = $scope.categories[i];
}
});
});
So how can I properly set the var categories to the required $http.get to retreive my server data into the filter above?
I think you should be able to get rid of the hard coded block in the service and just return:
return {
getCategories: $http.get('/categories').success(function (data) {
return data;
}),
getProducts: $http.get('/products').success(function (data) {
return data;
})
}
Make sure you dependencies are setup correctly for the service though (i.e. $http):
.factory('store', function ($http) {
// The above return block here
});
And this should do the trick!
I need parse the enclosure tag in order to get the url image. It's assumed I should get the MIXED OUTPUT with the json+xml code but I get a undefined value from the enclousure tag when I try parse it. I'm doing this like I saw at this post > Google Feed Loader API ignoring XML attributes < .In addition I tried to get the MIXED format writing the url manually but It doesn't work. There is my whole code. How could I know that Im getting the mixed json output?
var feeds = [];
var entryImageUrl = [];
angular.module('starter.controllers', ['ngResource','ngLocale'])
.factory('FeedLoader', function ($resource) {
return $resource('http://ajax.googleapis.com/ajax/services/feed/load', {}, {
fetch: { method: 'JSONP', params: {v: '1.0', callback: 'JSON_CALLBACK', output: 'json_xml'} }
});
})
.service('FeedList', function ($rootScope, FeedLoader) {
this.get = function() {
var feedSources = [
{title: 'Heraldo De Barbate', url: 'http://www.heraldodebarbate.es/rss/last'},
];
if (feeds.length === 0) {
for (var i=0; i<feedSources.length; i++) {
FeedLoader.fetch({q: feedSources[i].url, num: 10}, {}, function (data) {
var feed = data.responseData.feed;
**var entryImageUrl = feed.xmlNode.getElementsByTagName("enclosure")[i].getAttribute("url");**
feeds.push(feed);
});
}
}
return feeds;
};
})
.controller('FeedCtrl', function ($scope, FeedList,$timeout) {
$scope.update = function(){
$scope.feeds = FeedList.get();
$scope.$on('FeedList', function (event, data) {
$scope.feeds = data;
// $scope.entryImageUrl
console.log(feeds);
});
$timeout(function() {
$scope.$broadcast('scroll.refreshComplete');
}, 500);
}
})
How could I know that Im getting the mixed json output?
Use a test for tags within JSON:
function testMe(node)
{
return /</.test(JSON.stringify(node) )
}
then run it on the feed:
var mixed_format = testMe(feed);
and call another function which parses the data:
if (mixed_format)
{
mixed_parser(feed)
}
else
{
json_parser(feed)
}