Unable to get data from JSON file in AngularJS - angularjs

I'm new in angularjs, I'm trying to load data from my JSON file on view. JSON file have some list of lists using li. But does not get showed on my view.
Here is my 'index.html' file
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li ng-repeat="item in navbaritem.navigation">
<a class="{{ item.class }}" href="#" ng-href="{{ item.url }}">{{ item.title }}</a>
</li>
</ul>
</div>
Here is my controller.js
(function(){
var app = angular.module('myapp', []);
app.controller('mycntrl', function($scope, $http) {
$scope.navbaritem = [];
$http.get('pages/navbar.json').success(function(data) {
$scope.navbaritem = data;
}, function (err,data) {
if(err){
return console.log(err);
}
console.log(data);
});
});
});
Here is my 'pages/navbar.json' file
{
"general":{
"logo":"images/logo.jpeg",
"name" : "Company Name"
},
"navigation":[
{
"title":"Home",
"link":"#"
},
{
"title":"About",
"link":"#"
},
{
"title":"Services",
"link":"#"
},
{
"title":"Contact",
"link":"#"
}
]
}
and my output is like this {{item.title}} and also I'm getting the error
Uncaught Error: [$injector:modulerr] http://errors.angularjs.org/1.6.1/$injector/modulerr?p0=myapp&p1=Error%3A%2…localhost%2Fangular-theme%2Fassets%2Fangularjs%2Fangular.min.js%3A21%3A332)

Here is a working example :
Note: As SO snippet editor does not allow additional files, I simulated a $http call in my service with $timeout which also return a promise.
Snippet
(function() {
'use strict';
angular.module('app', []);
angular.
module('app')
.controller('ExampleController', ['$scope', 'MyService', function($scope, MyService) {
// Call service to get navbar items
MyService.getNavbarItems()
.then(function(data) {
// Once promise success, update $scope
$scope.navbaritem = data;
});
}])
.factory('MyService', ['$timeout', function($timeout) {
return {
getNavbarItems: function() {
// Simulate 250ms $http api call
// Use return $http.get('/api/navbar/items') in your code
return $timeout(function() {
return {
"general": {
"logo": "images/logo.jpeg",
"name": "Company Name"
},
"navigation": [{
"title": "Home",
"link": "/home",
"class": "item"
},
{
"title": "About",
"link": "/about"
},
{
"title": "Services",
"link": "/services"
},
{
"title": "Contact",
"link": "/contact"
}
]
}
}, 250);
}
}
}])
})();
<!doctype html>
<html lang="en" ng-app="app">
<head>
<meta charset="utf-8">
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.4/angular.min.js"></script>
</head>
<body ng-controller="ExampleController">
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav navbar-right">
<li ng-repeat="item in navbaritem.navigation">
<a class="{{ item.class }}" href="#" ng-href="{{ item.link }}">{{ item.title }}</a>
</li>
</ul>
</div>
</body>
</html>

Related

Displaying products from selected category in AngularJS

Below I have some AngularJS code to parse some JSON which lists all categories. I would like to display each product associated with a category when you click the category button, so when you click a category button, it should display a list of all the products within that category below. Here's what I have so far:
(function() {
var app = angular.module('store', []);
app.controller('StoreController', ['$scope', function($scope) {
var vm = this;
$scope.products = [{
"category": "Cat1",
"name": "Product1"
}, {
"category": "Cat1",
"name": "Product2"
}, {
"category": "Cat2",
"name": "Product3"
}, {
"category": "Cat3",
"name": "Product4"
}]
$scope.categories = Object.keys($scope.products.reduce(function(categoryMap, product) {
categoryMap[product.category] = 1;
return categoryMap;
}, {}));
vm.selectCategory = function(category) {
vm.selectedCategory = category;
}
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html lang="en" ng-app="store">
<body ng-controller="StoreController as vm">
<div ng-repeat="category in categories" class="category">
<button ng-click="vm.selectCategory(category);">{{category}}</button>
</div>
<!-- RESULTS -->
<div ng-repeat="product in vm.selectedCategory" class="product">
<p>{{product.name}}</p>
</div>
</body>
</html>
Since you are using controller as syntax, it is better to avoid all the $scope from your code. I am pushing all the products corresponding to selected category into a new array vm.selectedCategoryProjects.
(function() {
var app = angular.module('store', []);
app.controller('StoreController', ['$scope', function($scope) {
var vm = this;
vm.products = [{
"category": "Cat1",
"name": "Product1"
}, {
"category": "Cat1",
"name": "Product2"
}, {
"category": "Cat2",
"name": "Product3"
}, {
"category": "Cat3",
"name": "Product4"
}]
vm.categories = Object.keys(vm.products.reduce(function(categoryMap, product) {
categoryMap[product.category] = 1;
return categoryMap;
}, {}));
vm.selectCategory = function(category) {
vm.selectedCategoryProjects =[];
angular.forEach(vm.products,function(value,key){
if(value.category==category)
vm.selectedCategoryProjects.push(value.name);
});
}
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html lang="en" ng-app="store">
<body ng-controller="StoreController as vm">
<div ng-repeat="category in vm.categories" class="category">
<button ng-click="vm.selectCategory(category);">{{category}}</button>
</div>
<!-- RESULTS -->
<div ng-repeat="product in vm.selectedCategoryProjects" class="product">
<p>{{product}}</p>
</div>
</body>
</html>
For this issue you can use filter. so after selected a category filter product based on.
(function() {
var app = angular.module('store', []);
app.controller('StoreController', ['$scope', function($scope) {
var vm = this;
$scope.products = [{
"category": "Cat1",
"name": "Product1"
}, {
"category": "Cat1",
"name": "Product2"
}, {
"category": "Cat2",
"name": "Product3"
}, {
"category": "Cat3",
"name": "Product4"
}]
$scope.categories = Object.keys($scope.products.reduce(function(categoryMap, product) {
categoryMap[product.category] = 1;
return categoryMap;
}, {}));
vm.selectCategory = function(category) {
vm.selectedCategory = category;
}
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<html lang="en" ng-app="store">
<body ng-controller="StoreController as vm">
<div ng-repeat="product in products" class="category">
<button ng-click="vm.selectCategory(product.category);">{{product.category}}</button>
</div>
<!-- RESULTS -->
<div ng-if="vm.selectedCategory" ng-repeat="product in products | filter:{category:vm.selectedCategory}" class="product">
<p>{{product.name}}</p>
</div>
</body>
</html>
just do this:
<!-- RESULTS -->
<div ng-repeat="product in products" class="product" ng-if="vm.selectedCategory && vm.selectedCategory === product.category">
<p>{{product.name}}</p>
</div>

ng-repeat not working while ng-view redirect to another page

while i am calling {{jeans.title}} in product page its not working.
my app.js code:-
<!-- Modules -->
var app = angular.module('GalleryApp', ['ngRoute']);
<!-- routeProvider -->
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'HomeController',
templateUrl: 'views/home.html'
})
.when('/products/:id', {
controller: 'ProductsController',
templateUrl:'views/product.html'
})
.otherwise({ redirectTo: '/' });
});
<!-- Controllers -->
app.controller('HomeController', ['$scope', 'products', function($scope, products) {
products.success(function(data1) {
$scope.products = data1;
});
}]);
app.controller('ProductsController', ['$scope', 'products', '$routeParams', function($scope, products, $routeParams) {
products.success(function(data2) {
jeans = data2[$routeParams.id];
});
}]);
<!-- services -->
app.factory('products', ['$http', function($http) {
return $http.get('products.json')
.success(function(data) {
return data;
});
}]);
index.html:-
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link href="https://fonts.googleapis.com/css?family=Roboto:400,500,300" rel="stylesheet" type="text/css">
<link href="css/main.css" rel="stylesheet" />
<!-- Include the core AngularJS library -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.5/angular.min.js"></script>
<!-- Include the AngularJS routing library -->
<script src="https://code.angularjs.org/1.2.28/angular-route.min.js"></script>
</head>
<body ng-app="GalleryApp">
<div ng-view></div>
<script src="js/app.js"></script>
</body>
</html>
home.html:-
<div class="container">
<div class="row" ng-repeat="men in products.mens">
<div class="col-sm-4" ng-repeat="jean in men.jeans">
<p>{{ jean.title }}</p>
<img ng-src="{{ jean.img }}" alt="{{ jean.brand }}" title="{{ jean.brand }}"/>
<h3>{{ jean.brand }}</h3>
<h4>{{ jean.model }}</h4>
</div>
</div>
</div>
product.html:-
<div class="container">
<div class="row">
<div class="col-sm-6">
<p>{{ jeans.title }}</p>
</div>
</div>
</div>
Product.json:-
{
"mens": [
{
"name": "mens fasion",
"jeans": [
{
"title": "Slim fit",
"model": "slim 2527",
"brand": "Tommy Hilfiger",
"img": "images/mens/jeans/product_1.jpg",
"price": "2000",
"offer": "10"
},
{
"title": "Parallel",
"model": "Parallel-1575",
"brand": "Denim",
"img": "images/mens/jeans/product_2.jpg",
"price": "2500",
"offer": "15"
},
{
"title": "cargos",
"model": "cargos 2876",
"brand": "Lee Cooper",
"img": "images/mens/jeans/product_3.jpg",
"price": "3000",
"offer": "20"
}
]
}
]
}
while i am calling {{jeans.title}} in product page its not working.
In ProductsController
jeans = data2[$routeParams.id];
you are missing $scope.. It should be:
$scope.jeans = data2[$routeParams.id];
Also, it seems that you want to access the sub-object mens[0].jeans within your JSON object here:
$scope.jeans = data2.mens[0].jeans[$routeParams.id];

ng-repeat passes only first element to the function

I have following code in my app:
<li ng-repeat="data in array">
<ul class="social-share">
<li>
<i class="fa fa-share-alt"></i>Share
<div id="myPopover" class="hide">
<strong>Social Share</strong>
<ul class="social-spacing">
<li><a class="btn btn-primary share-button" title="" data-original-title="" href="" ng-click="share(data.translation)">Facebook</a></li>
</ul>
</div>
</li>
</ul>
<p class="eng-translation">{{data.translation}}</p>
</li>
I'm using an angular directive to show the popover which contains social sharing options. Directive is as follows:
myApp.directive('popover', function() {
return function(scope, elem) {
elem.popover({
container: 'body',
html: true,
content: function () {
var clone = $($(this).data('popover-content')).clone(true).removeClass('hide');
return clone;
}
}).click(function(e) {
e.preventDefault();
});
}
});
All of the data in array displays properly as is supposed to be with ng-repeat. But, when I click on the Facebook share button, it only sends the first element of the array to the function "share".
If I don't use popover, it works fine.
Any help on this would be really kind.
Edit: Array object added
$scope.array = [
{
'translation': 'translation-1'
},
{
'translation': 'translation-2'
},
{
'translation': 'translation-3'
},
{
'translation': 'translation-4'
},
{
'translation': 'translation-5'
},
{
'translation': 'translation-6'
},
{
'translation': 'translation-7'
}
];
You can find the working version of your code below here. Are you missing to add ng-app="app" or ng-controller="myController" elements?
var myApp = angular.module('app', []);
myApp.controller('myController', ['$scope', function($scope) {
$scope.myArray = [
{
'translation': 'translation-1'
},
{
'translation': 'translation-2'
},
{
'translation': 'translation-3'
},
{
'translation': 'translation-4'
},
{
'translation': 'translation-5'
},
{
'translation': 'translation-6'
},
{
'translation': 'translation-7'
}
];
$scope.share = function($index) {
alert($scope.myArray[$index].translation);
};
}]);
myApp.directive('popover', function() {
return function(scope, elem) {
elem.popover({
container: 'body',
html: true,
content: function () {
var clone = elem.siblings('#myPopover').clone(true).removeClass('hide').css("display", "inherit");
return clone;
}
}).click(function(e) {
e.preventDefault();
});
}
});
<html>
<head>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.20/angular.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
<div ng-app="app">
<div ng-controller="myController">
<li ng-repeat="myData in myArray">
<ul class="social-share">
<li>
</i>Share
<div id="myPopover" class="hide">
<strong>Social Share</strong>
<ul class="social-spacing">
<li><a class="btn btn-primary share-button" title="" data-original-title="" href="" ng-click="share($index)">Facebook</a></li>
</ul>
</div>
</li>
</ul>
<p class="eng-translation">{{myData.translation}}</p>
</li>
</div>
</
</body>
</html>

Change scope value on ng-click

I would like to use tabs to hide and show items in an ng-repeat. Is it possible to change the value of a scope like so?
<a ng-click="packageType = '1'">Package 1</a><a ng-click="packageType ='2'">Package 2</a><a ng-click="packageType = '3'">Package 3</a>
<div ng-repeat="item in packages" ng-show="packageType >=item.packageID">
{{item.name}}</div>
and the scope:
$scope.packages = [...{ "name": "some name",
"packageID": 1}...]
Where packageID can be 1, 2 or 3?
Here's the code that does exactly what your asking
Plunker
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
<script src="http://angular-ui.github.com/bootstrap/ui-bootstrap-tpls-0.6.0.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.2/css/bootstrap.css" rel="stylesheet">
</head>
<body ng-controller="MainCtrl">
<div ng-controller="TabCtrl">
<tabset>
<tab ng-repeat="tab in tabs" heading="{{tab.name}}" active="tab.active" select="onTabSelected(tab.slug)">
{{ tab.packageId }}
</tab>
</tabset>
</div>
<script type="text/javascript" charset="utf-8">
angular.module('app', ['ui.bootstrap']).config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider.when('/', {
controller: 'MainCtrl'
}).when('/room/:id', {
controller: 'RoomCtrl',
}).when('/dashboard', {
controller: 'DashboardCtrl'
}).otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(false);
}]);
var TabCtrl = function($scope) {
$scope.tabs = [{
slug: 'dashboard',
name: "Package 1",
packageId: "some package #1"
}, {
slug: 'room-1',
name: "Package 2",
packageId: "some package #2"
}, {
slug: 'room-2',
name: "Package 3",
packageId: "some package #3"
}];
};
RoomCtrl = function($scope, $location) {
};
DashboardCtrl = function($scope, $location) {
};
MainCtrl = function($scope, $location) {
$scope.onTabSelected = function(tab) {
var route;
if (typeof tab === 'string') {
switch (tab) {
case 'dashboard':
route = tab;
break;
default:
route = 'rooms/' + tab;
break;
}
}
$location.path('/' + route);
};
};
</script>
</body>
</html>
I would write a function that encapsulates what you want to happen on click. That would make it easier to understand.
So I assume packages is an array and what you posted is not your complete code.
You will want to change your ng-show to say
ng-show="packageType == item.packageID"
this will only show the div if the packageID is the same as the package type. Your ng-click should work fine. You will want to set a default value for packageType somewhere in your controller however so something shows initially
You code has a few problems:
You first ng-click is does not have a closing quote.
<a ng-click="packageType = '1'>Package 1</a>
You set packageType to a string when it is a number later:
packageType ='2'
$scope.packages = { "name": "some name",
"packageID": 1}
You don't need {{}} in the ng-show
ng-show="packageType >={{item.packageID}}"
I think you meant for packages to be an array instead of an object:
$scope.packages = { "name": "some name",
"packageID": 1}
Example of how to do it is below. I set it to show on the second and third links :
(function() {
'use strict';
angular
.module('exampleApp', [])
.controller('ExampleController', ExampleController);
function ExampleController($scope) {
var vm = this;
$scope.packageType = 1;
$scope.packages = [{
"name": "some name1",
"packageID": 2
}, {
"name": "some name2",
"packageID": 2
}, {
"name": "some name3",
"packageID": 2
}, {
"name": "some name4",
"packageID": 3
}, {
"name": "some name5",
"packageID": 3
}, {
"name": "some nam6",
"packageID": 3
}];
}
ExampleController.$inject = ['$scope'];
})();
<!DOCTYPE html>
<html ng-app='exampleApp'>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
</head>
<body ng-controller="ExampleController">
<a ng-click="packageType = 1">Package 1</a>
<a ng-click="packageType = 2">Package 2</a>
<a ng-click="packageType = 3">Package 3</a>
<p ng-repeat="item in packages" ng-show="packageType >= item.packageID">{{item.name}}
</p>
</body>
</html>

ui-router dots in name not working

The UI-Router docs shows that you can use dots in route name:
<!-- partials/state1.html -->
<h1>State 1</h1>
<hr/>
<a ui-sref="state1.list">Show List</a>
<div ui-view></div>
But however in my app this doesn't work. This is an example that worked fine until I changed client to client.ts everywhere:
<!DOCTYPE html>
<html ng-app="myapp">
<head>
<title>AngularJS: UI-Router Quick Start</title>
<!-- Bootstrap CSS -->
<link href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.3.1/css/bootstrap.min.css" rel="stylesheet">
</head>
<body class="container">
<div class="navbar">
<div class="navbar-inner">
<a class="brand" ui-sref="index">Quick Start</a>
<ul class="nav">
<li><a ui-sref="index">Home</a></li>
<li><a ui-sref="clien.ts">Clients</a></li>
<li><a ui-sref="route1">Route 1</a></li>
</ul>
</div>
</div>
<div class="row">
<div class="span6">
<div class="well" ui-view=""></div>
</div>
<div class="span6">
<div class="well" ui-view="viewB"></div>
</div>
</div>
<!-- Angular -->
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
<!-- UI-Router -->
<script src="//angular-ui.github.io/ui-router/release/angular-ui-router.js"></script>
<!-- App Script -->
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider){
$stateProvider
.state('index', {
url: "",
views: {
"": {
template: "index.viewA-index"
},
"viewB": {
template: "index.viewB"
}
}
})
.state('route1', {
url: "/route1",
views: {
"": {
template: "route1.viewA-route1"
},
"viewB": {
template: "route1.viewB"
}
}
})
.state('clien.ts', {
url: "/clients",
views: {
"viewB": {
template: "clients.viewA-route2"
},
"": {
controller: function($scope, ClientService) {
console.log('Controller code being run');
$scope.clients = ClientService.clientList();
},
templateUrl: 'client-list-template.html'
}
}
})
})
.service('ClientService', function() {
this.clientList = function() {
clients = [{'name': 'Acme Food', 'description': 'Makers of fine food'},
{'name': 'Dog Biscuits Inc', 'description': 'Cruncy creations for canines'},
{'name': 'Parrot treats Ltd', 'description': 'Puveyors of bird food'},
{'name': 'Pond supplies', 'description': 'Sell fish and gravel'}];
return(clients);
}
});
</script>
</body>
</html>
Plunker here: http://plnkr.co/edit/ZD7WlC9aKzpwte9dVMxC?p=preview
As you can see the link can't be clicked :/
What you need to do is add an abstract state for clien in that case.
Here's the plunkr, with the added state: plunkr
Whenever you define states with the dot. You still need to at least define the abstract state for the child. In your case for clien.
Also something from the docs
If you register only a single state, like contacts.list, you MUST define a state called contacts at some point, or else no states will be registered. The state contacts.list will get queued until contacts is defined. You will not see any errors if you do this, so be careful that you define the parent in order for the child to get properly registered.

Resources