I am trying to display nested JSON in a page. I'm not sure how to drill down into it.
In my app js file I have an parameter called initialData that I want to call a function getProducts() when the view is called...
'use strict';
var quoteApp = angular.module('quoteApp', ['ui.router']);
quoteApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
// HOME STATES AND NESTED VIEWS ========================================
.state('home', {
url: '/home',
templateUrl: 'ng-views/choose.html',
controller: "quoteBuilderController",
resolve: {
initialData: ['quoteApi', function (quoteApi) {
return quoteApi.getProducts();
}]
}
})
});
my quoteApi looks like this in case you want to see it...
(function () {
'use strict';
angular.module('quoteApp').factory('quoteApi', quoteApi);
quoteApi.$inject = ['$http'];
function quoteApi($http) {
var service = {
getProducts: getProducts,
getPrices: getPrices
};
var baseUrl = 'http://www.website.com/api/Pricing';
return service;
function getProducts() {
return httpGet('/GetProductCatalogue');
}
function getPrices() {
return httpGet('/GetPrices');
}
/** Private Methods **/
function httpExecute(requestUrl, method, data){
return $http({
url: baseUrl + requestUrl,
method: method,
data: data,
headers: requestConfig.headers }).then(function(response){
return response.data;
});
}
function httpGet(url){
return httpExecute(url, 'GET');
}
}
})();
So quoteApi.getProducts() returns JSON that looks like this...
{
"Cat1": [
{
"product_id": 1,
"product_name": "Prod1"
},
{
"product_id": 2,
"product_name": "Prod2"
}
],
"Cat2": [
{
...
}
]
}
My controller for the view looks like this...
(function () {
'use strict';
angular.module('quoteApp').controller('quoteController', ['$scope', '$http', '$timeout', quoteController]);
quoteController.$inject = ['initialData', 'quoteApi'];
function quoteController($scope, initialData) {
$scope.cat1Products = initialData;
};
})();
So my question is, how can I get 'initialData' to load products from Cat1 only? Should I try to do this from the html? It seems like it should be straight forward enough but I can seem to get it. Thank you.
You need to transform your response from your http request further so you only return the piece you require, and you may also want to consider using the .then() approach:
$http.get('/someUrl').then(function(response) {
//Do something with response.data.Cat1 here
}, function(errResponse) {
console.error('Error while fetching data');
});
Just take out cat1 from your initialData object
function quoteController($scope, initialData) {
$scope.cat1Products = initialData['Cat1'];
};
Related
I use the Tab Template, with list of chats and chats detail. I've put the data into a json file, and add it like this in my code : $http.get("http://abcd/Chats.json").
The data are showing on the List of Chats, but it doesn't work on the Detail Page.
I've tested a lot of solution, but I'm still getting an error...
Here is my code:
SERVICE
angular.module('starter.services', [])
.factory('Chats', function($http) {
// Might use a resource here that returns a JSON array
return {
getChats: function() {
return $http.get("http://abcd/Chats.json").success(function(response){
chats=response;
return chats;
});
},
get: function(chatId) {
for (var i = 0; i < chats.length; i++) {
if (chats[i].id === parseInt(chatId)) {
return chats[i];
}
}
return null;
}
};
});
CONTROLLER
.controller('ChatsCtrl', function($scope, Chats) {
Chats.getChats().success(function(response){
$scope.chats =response;
});
})
.controller('ChatDetailCtrl', function($scope, $stateParams, Chats) {
$scope.chat = Chats.get($stateParams.chatId);
} )
My error is: cannot read property of chat undefined..
Any help please?
Try to define chats as a var inside your factory.
.factory('Chats', function($http) {
var chats;
...
I have the following code that has static JSON content (which is working in its current state). Now, I want to call a remote JSON service to get the data instead of static content. I made a fake web service to return the same JSON data: http://appserver.falconinet.com/events.lasso
So here's what I have now. I think I am close...?
angular.module('starter.services', [])
.factory('Events', function ($http) {
var events = [];
return {
all: function () {
return $http.get("http://appserver.falconinet.com/events.lasso");
starter.services.all().then(function successCallback(response) {
$scope.events = data;
})
}
}
return {
all: function () {
return events;
},
remove: function (event) {
events.splice(events.indexOf(event), 1);
},
get: function (eventId) {
for (var i = 0; i < events.length; i++) {
if (events[i].id === parseInt(eventId)) {
return events[i];
}
}
return null;
}
}
})
And here's my controller:
// events
.controller('EventsCtrl', function ($scope, Events) {
$scope.events = Events.all();
console.log($scope.events);
$scope.remove = function (event) {
Events.remove(event);
}
})
.controller('EventDetailCtrl', function ($scope, $stateParams, Events) {
$scope.event = Events.get($stateParams.eventId);
})
Your factory is perfect, just return events when you removed in order to see the modifications :
appModule.factory('Events', function() {
// Might use a resource here that returns a JSON array
// Some fake testing data
var events = [{
id: 0,
title: 'Swing Dance Party',
subtitle: 'Lets Get Dancing!',
when: 'Thursday, Feb 19, 2015 (6:30-9PM)',
picture: 'http://goldsea.com/Text/images/8198.jpg',
desc: 'Dance, dance, dance and enjoy mixed drinks, wine, or 40 beers on tap. Krista Mccart & Steve Davis will be doing a short 30 minute class for first time beginners at 6:30 and the dance starts at 7:00. The dance and lesson are free!!!'
}, {
id: 1,
title: 'St. Patricks Day Party',
subtitle: 'with Special Guest The Menders',
when: 'Saturday, March 14th (9PM)',
picture: 'img/menders.png',
desc: 'Based out of Gastonia, NC, The Menders have been blending influences such as the Beatles, Jack White, The Doors, and Ryan Adams into a folk-laced garage rock sound. Since 2011, they\'ve been honing their craft around NC at venues such as Double Door Inn, The Visulite, The Milestone, Tremont Music Hall, and Snug Harbor. With an upcoming debut self-titled album, lyrics dealing with the complexities of life and death, 4 part harmonies, and energetic live performances, The Menders seek to offer their fans and listeners a music experience that is sure to leave a lasting impression.'
}];
return {
all: function() {
return events;
},
remove: function(event) {
events.splice(events.indexOf(event), 1);
return events;
},
get: function(eventId) {
for (var i = 0; i < events.length; i++) {
if (events[i].id === parseInt(eventId)) {
return events[i];
}
}
return null;
}
}
})
Now create your controller :
appModule.controller('EventsCtrl', ['$scope', 'Events', function($scope, Event) {
var events = Event.all();
console.log('events', events);
var first_event = Event.get(0);
console.log('first_event', first_event);
$scope.remove = function(event) {
console.log(Events.remove(event));
}
}]);
In your case, you need to define a controller and inside of this, inject the Events factory.
In the «all» method: $http.get("http://appserver.falconinet.com/events.lasso"); will return a promise, so in the controller, you need to implement the .then() function, then you can assign the json response data in the $scope.events array.
Something like this:
(function() {
angular.module("starter.services", [])
// Controller
.controller("EventsCtrl", ["$scope", "Events", function($scope, Events) {
$scope.events = [];
Events.all().then(function(response) {
$scope.events = response.data;
});
$scope.remove = function(event) {
$scope.events.splice(event, 1);
}
}
])
// Factory service
.factory("Events", ["$http", function($http) {
return {
all: function() {
return $http.get("http://appserver.falconinet.com/events.lasso");
}
}
}
]);
})();
<html data-ng-app="starter.services">
<head>
<meta charset="utf-8" />
<title>Demo</title>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
</head>
<body data-ng-controller="EventsCtrl">
<div>
<ul>
<li data-ng-repeat="event in events">{{event.title}} Remove
</li>
</ul>
</div>
</body>
</html>
You'll want to use angularjs [$http service]1
return {
all: function() {
return $http.get("http://appserver.falconinet.com/events.lasso");
},
[edit]: Also keep in mind that $http requests will be called asynchronously, so if you are injecting this factory into a controller you'll need bind any variables on success. E.g.:
starter.services.all().then(function successCallback(response) {
$scope.variableName = data;
})
[edit]: In response to your suggested edits, you're missing some of the key differences between where you should be setting scope variables (in the controller) and where your factory is calling. To demonstrate, I made a working plunk with what you're trying to accomplish: http://plnkr.co/edit/IlIPXHMkkw6lo08eZVIk?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope, Events) {
Events.all().then(function successCallback(response) {
$scope.events = response.data;
});
});
app.factory('Events', function($http) {
return {
all: function() {
return $http.get("http://appserver.falconinet.com/events.lasso");
}
}
});
I try to use ng-tags-input with a returned Json list by an api controller .net Mvc 6. My list is created in json but when try to display this list with the autocompletion , nothing works. My autocomplete list isn't displayed and I don't have error in chrome console.
So this is an object of my list :
[{
"ShopID":1,
"CompanyID":1,
"RegionID":1,
"Name":"Les Pieux",
"Town":"Les Pieux",
"Address":null,
"ZipCode":null,
"CreateDate":"2006-01-01T00:00:00",
"ModificationDate":"2006-09-29T00:00:00",
"LastModificationUserID":1,
"PhoneNumber":null,
"Fax":null,
"Email":null,
"CEmployeeShop":null
}]
This is my method in my controller:
$scope.tokenShops = [];
$scope.loadJsonShops = function(query)
{
//$scope.shops contains my list of shops in json format.
return $scope.shops;
}
And the tag in Html:
<div ng-controller="EmployeesCtrl">
<tags-input ng-model="tokenShops"
display-property="Name"
Placeholder="Ajouter un magasin"
add-from-autocomplete-only="true">
<auto-complete resource="loadJsonShops($query)"></auto-complete>
</tags-input>
</div>
This is my code that populates $scope.shops
Api Controller:
public IEnumerable<Shop> Get()
{
using (LSContext db = new LSContext())
{
var listShop = db.Shops.ToList();
return listShop;
}
}
angular shopCtrl:
function ShopsCtrl($scope, $http, $rootScope) {
function getShopsList() {
var reqGetShops = $http({ url: 'api/Shops' });
reqGetShops.success(function (data) {
$scope.shops = data;
$rootScope.$broadcast("getListShops", { list: data });
});
}
//with api controller the list is returned in json format. I tried an another method to fill my list with an convertion that I do and it doesn't work.
angularjs EmployeeCtrl :
$scope.$on("getListShops", function (event, args) {
$scope.shops = args.list;
$scope.selectShop = args.list[0];
})
But I don't think that my problem from my json list.
I hope someone can help me . Have a nice day.
I resolve my problem with a directive:
angular.module('TagsDirective', ['myResources', 'resourcesManagerGet', 'translateI18n'])
.directive('tags', function ($http, $q) {
return {
restrict: 'E',//restraint pour les éléments du dom
template: '<tags-input ng-model="SShops" key-property="ShopID" display-property="Name" placeholder="{{\'AddShop\' | i18n}}" add-from-autocomplete-only="true"><auto-complete source="loadTags($query)"></auto-complete></tags-input>',
scope: false,
link: function (scope, el) {
scope.loadTags = function (query) {
var deferred = $q.defer();
var reqGetShops = $http({ url: 'api/Shops/GetListShopFiltered', params: { 'query': query } });
reqGetShops.success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
}
});
and in Html:
<tags></tags>
g0loob : thanks for your help, but now you can put an array of objects and use the attribute display-property to choose the text property to display.
example:http://mbenford.github.io/ngTagsInput/demos and look the tags input with custom object.
auto-complete requires array of objects with at least one property named "text" (just like tags-input), if you are not using your template for auto-complete or tags-input. And you also need to filter your result for auto-complete in order to work properly. Also see this link.
angular.module('TagsDirective', ['myResources', 'resourcesManagerGet', 'translateI18n'])
.directive('tags', function ($http, $q) {
return {
restrict: 'E',//restraint pour les éléments du dom
template: '<tags-input ng-model="SShops" key-property="ShopID" display-property="Name" placeholder="{{\'AddShop\' | i18n}}" add-from-autocomplete-only="true"><auto-complete source="loadTags($query)"></auto-complete></tags-input>',
scope: false,
link: function (scope, el) {
scope.loadTags = function (query) {
var deferred = $q.defer();
var reqGetShops = $http({ url: 'api/Shops/GetListShopFiltered', params: { 'query': query } });
reqGetShops.success(function (data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
}
I would like to display data returned from service call into view:
Service Code :
.service('HomeExchangeList', function ($rootScope, $http, $log) {
this.getHomeExchange = function() {
var rates = $http({
method: 'GET',
url: 'http://localhost:8080/feeds/homerates_android.php'
}).success(function (data) {
$log.log(data);
return data;
});
return homeRates;
};
})
JSON Data returned by service
{
"record":[
{
"Name":"GBP\/USD",
"Ticker":"GBP\/USD",
"Price":"0.5828",
"Open":"0.5835",
"High":"0.5848",
"Low":"0.5828",
"PercentagePriceChange":"0.1371",
"Movement":"0.0800",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"EUR\/USD",
"Ticker":"EUR\/USD",
"Price":"0.7330",
"Open":"0.7344",
"High":"0.7351",
"Low":"0.7327",
"PercentagePriceChange":"0.2585",
"Movement":"0.1900",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"GHS\/USD",
"Ticker":"GHS\/USD",
"Price":"3.3350",
"Open":"3.2650",
"High":"3.3500",
"Low":"3.2650",
"PercentagePriceChange":"0.8915",
"Movement":"3.0000",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"KES\/USD",
"Ticker":"KES\/USD",
"Price":"87.7000",
"Open":"86.2970",
"High":"87.6500",
"Low":"86.1800",
"PercentagePriceChange":"0.0661",
"Movement":"5.8000",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"MUR\/USD",
"Ticker":"MUR\/USD",
"Price":"30.2925",
"Open":"29.1460",
"High":"29.4300",
"Low":"29.0500",
"PercentagePriceChange":"-0.0909",
"Movement":"-2.7500",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"MWK\/USD",
"Ticker":"MWK\/USD",
"Price":"393.5000",
"Open":"393.3900",
"High":"393.3900",
"Low":"385.0000",
"PercentagePriceChange":"-0.2548",
"Movement":"-100.0000",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"NGN\/USD",
"Ticker":"NGN\/USD",
"Price":"162.3000",
"Open":"160.0600",
"High":"162.4000",
"Low":"160.0600",
"PercentagePriceChange":"0.2459",
"Movement":"40.0000",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"ZAR\/USD",
"Ticker":"ZAR\/USD",
"Price":"10.6659",
"Open":"10.6751",
"High":"10.7162",
"Low":"10.6523",
"PercentagePriceChange":"0.9840",
"Movement":"10.6000",
"DateStamp":"2014\/07\/09",
"TimeStamp":"22:15:00"
},
{
"Name":"ZMK\/USD",
"Ticker":"ZMK\/USD",
"Price":"47.7014",
"Open":"47.3850",
"High":"47.7000",
"Low":"46.8900",
"PercentagePriceChange":"0.0067",
"Movement":"0.3165",
"DateStamp":"2013\/07\/27",
"TimeStamp":"01:55:00"
}
]
}
Controller code
function HomeCtrl($scope, Page, $location, HomeExchangeList) {
$scope.rates = HomeExchangeList.getHomeExchange();
$scope.$on('HomeExchangeList', function (event, data) {
$scope.exchangeRates = data;
});
}
View
<ul id="home-rates" ng-repeat="rate in exchangeRates">
<li><span class='rate-symbol'>{{rate.Name}}</span><span class='rate-amount'>{{rate.Price}}</span></li>
</ul>
I would like to display the data returned by in the service in the view but it doesn't seem to be working. Please help
First, $http invocations all return a promise, not the result of your request. Your service should just return the result of the $http call, and your controller needs to attach a .success handler to receive the data and set it on the scope of your controller.
.service('HomeExchangeList', function ($rootScope, $http, $log) {
this.getHomeExchange = function() {
var rates = $http({
method: 'GET',
url: 'http://localhost:8080/feeds/homerates_android.php'
}).success(function (data) {
$log.log(data);
// removed your return data; it doesn't do anything, and this success is only added to log the result. if you don't need the log other than for debugging, get rid of this success handler too.
});
return rates;
};
})
function HomeCtrl($scope, Page, $location, HomeExchangeList) {
HomeExchangeList.getHomeExchange().success(function(data) {
$scope.exchangeRates = data;
});
}
Second, the root of your JSON is not an array, so you can't enumerate through just exchangeRates alone. Perhaps you meant exchangeRates.record.
try to assign data.record to $scope.exchangeRates instead of data... as data doesnt hold the array of records... it holds record which then holds the array
First of all, your service function always returns undefined:
var rates = ...,
return homeRates;
It should be
return rates;
Second, once that is fixed, the service doesn't return data. It returns a promise, and you can't iterate on a promise. What you need in the controller is:
HomeExchangeList.getHomeExchange().then(function(data) {
$scope.rates = data.record;
}
The call to $scope.$on doesn't make any sense. $scope.$on is used to listen for events. Not to get data from a promise.
And finally, your view must iterate over these retes, and not over exchangeRates:
ng-repeat="rate in rates">
I have below ajax query which returns me json from controller
$(document).ready(function () {
$.getJSON(
"api/OutletPOC/GetHomeTab?bizId=1",
function (data) {
$("#homeTabDesc").append(data.HomeDesc);
$(".test").hide();
$("#hometabcontent").show();
});
});
the controller action is as below
[System.Web.Http.ActionName("GetHomeTab")]
public HomeTabModel GetHomeTab(int bizId)
{
var outlet = db.Info.Where(t => t.BizId == bizId).SingleOrDefault();
return new HomeTabModel
{
HomeDesc = outlet.BizHomeDesc,
HomeTabText = outlet.BizHomeTabText
};
}
Now my question is: curently i am sending hard coded value of bizId to web api. I want to send this value dynamically. How can i achieve this? I have that value in my route config file. The code is as below-
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{bizId}",
defaults: new { controller = "Home", action = "Index", bizId = 1 }
);
}
I am new to this. Please help! Thanks in advance!
no, actually after much research, i came up with this solution and this works fine for me....
In controller,
public ActionResult Index(int bizId)
{
ViewBag.BizId = bizId;
return View();
}
and in View,
$(document).ready(function () {
$.getJSON(
"api/OutletPOC/GetHomeTab?bizId=#ViewBag.BizId",
function (data) {
$("#homeTabDesc").append(data.HomeDesc);
$(".test").hide();
$("#hometabcontent").show();
});
});
You can pass a data object as part of the GetJson call.
$(document).ready(function () {
$.getJSON(
"api/OutletPOC/GetHomeTab",{bizId : 1},
function (data) {
$("#homeTabDesc").append(data.HomeDesc);
$(".test").hide();
$("#hometabcontent").show();
});
});
Taking this one step further you could wrap this in a function.
function makeCall(id)
{
$.getJSON("api/OutletPOC/GetHomeTab",{bizId : id},
function (data) {
$("#homeTabDesc").append(data.HomeDesc);
$(".test").hide();
$("#hometabcontent").show();
});
}
Also look into using promises.
$.getJSON().then().done();