I'm a newbie to Angular. I need to render a dynamic content from JSON file using AngularJS 1.6. Here is what I have.
News.json
{
"Articles": [
{
"Title": "News 1",
"Abstract": "News 1 abstract ...",
"Body": "News 1 starts here.... ",
"Comments": [
{
"comment 1" : "Comment 1 goes here",
"comment 2" : "Comment 2 goes here",
"comment 3" : "Comment 3 goes here"
}]
},
{
"Title": "News 2",
"Abstract": "News 2 abstract ... ",
"Body": "News 2 starts here...",
"Comments": [
{
"comment 1" : "Comment 1 goes here",
"comment 2" : "Comment 2 goes here"
}]
}
]
}
Script.js
app.config(function ($routeProvider) {
$routeProvider
.when("/News", {
templateUrl: "NewsViewer.html",
controller: "showNews"
});
});
app.controller("showNews", ["$scope", "$http", function ($scope, $http) {
$http({
method: 'GET',
url: 'News/News.json'
}).then(function success(data) {
$scope.News = data.data;
});
}]);
News.html
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-1 col-md-6">
<div ng-controller="NewsRendering">
<div ng-repeat="NewsData in News.Articles">
<h3>{{NewsData.Title}}</h3>
<p>{{NewsData.Abstract}}</p>
<a data-ng-href="/AngularTask/NewsViewer.html">more</a>
</div>
</div>
</div>
<div class="col-md-4 questionnaire">
<h3>Questionnaire of the day</h3>
</div>
</div>
</div>
NewsViewer.html
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-1 col-md-6">
<div ng-controller="showNews">
<div>
<h3>{{News.Articles[0].Title}}</h3>
<p>{{News.Articles[0].Abstract}}</p>
<p>{{News.Articles[0].Body}}</p>
</div>
<div class="comments">
<h4>Comments</h4>
<hr>
<p>{{News.Articles[0].Comments[0]}}</p>
</div>
</div>
</div>
</div>
</div>
This code is working fine, but this code is not dynamic. My problem how to make it dynamic and can show whatever in json file. What should I do in JS code to pass the index of the array of the JSON File.
As you can see <h3>{{News.Articles[0].Title}}</h3> is showing only the first Title of the JSON file. I need to write it to be <h3>{{News.Articles[index of whatever].Title}}</h3>
Note: News.json has around 100,000 records. I make it two, just to show the code and describe the problem.
I think what you need is using 'ng-repeat' to show the Array Articles and '$http.get()' to load the json.file "dynamically" as you want.
ng-repeat : angularjs docs
load JSON : #1 see this link, loading a json file
#2 see this link, loading a json file
You need to use a routing service in combination with the rootScope to save the selected object. I made an easy example for you:
angular
.module('myApp', ['ngRoute'])
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/list', {
templateUrl: 'pages/list.html',
controller: 'listController'
})
.when('/details', {
templateUrl : 'pages/details.html',
controller: 'displayController'
})
.otherwise({redirectTo: '/list'});
}])
.controller('listController', function($scope, $rootScope) {
var myObject = {
Listoflinks: [{
"Title": "Link 1",
"Abstract": "abstract is here ....",
"Body": "Body is here ...",
},
{
"Title": "Link 1",
"Abstract": "abstract is here ....",
"Body": "Body is here ...",
}]
}
$rootScope.detail = myObject.Listoflinks[0];
})
.controller('displayController', function($scope, $rootScope) {
$scope.detail = $rootScope.detail;
});
https://plnkr.co/edit/0SYnFcjlgGyTowlcpvgz?p=catalogue
You can do it by passing the index of the news to the /News route.
First, change News.html so it tracks the data by index, and then appends the index of the item to the ng-href.
<div ng-repeat="NewsData in News.Articles track by $index">
<h3>{{NewsData.Title}}</h3>
<p>{{NewsData.Abstract}}</p>
<a data-ng-href="/AngularTask/NewsViewer.html?index={{$index}}">more</a>
</div>
Now, for each visit, you will see a new query parameter in the NewsViewer route, which will be index.
Second, change the controller, so it takes the advantage of passed index using $routeParams.
app.controller("showNews", ["$scope", "$http", "$routeParams",
function ($scope, $http, $routeParams) {
$http({
method: 'GET',
url: 'News/News.json'
}).then(function success(data) {
$scope.News = data.data.Articles[$routeParams.index];
});
}]);
This way, $scope.News will contain the article which resides on the passed index.
Finally, change NewsViewer.html so that it uses $scope.News.
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-1 col-md-6">
<div ng-controller="showNews">
<div>
<h3>{{News.Title}}</h3>
<p>{{News.Abstract}}</p>
<p>{{News.Body}}</p>
</div>
<div class="comments">
<h4>Comments</h4>
<hr>
<p>{{News.Comments[0]}}</p>
</div>
</div>
</div>
</div>
</div>
For comments, you can again use ng-repeat directive to show all the comments, iterating over them one-by-one.
Hope this answers your question.
Few observations as per your code :
This line of code <a data-ng-href="/AngularTask/NewsViewer.html">more</a> will break the pupose of AngularJS which is Single page application (SPA).
Use ui-router instead of ngRoute to get better as ngRoute is outdated.
Instead of redirecting a user to a html template (/AngularTask/NewsViewer.html) directly, change the state of the view using ui-sref with params and pass the $index as param value.
Try below approach to get result as per the expectation :
News.html
<div ng-repeat="NewsData in News.Articles">
<h3>{{NewsData.Title}}</h3>
<p>{{NewsData.Abstract}}</p>
more
</div>
routes.js :
$stateProvider
.state('newsdetails', {
url: '/news-details/:index',
controller: 'showNews',
templateUrl: 'NewsViewer.html'
})
....
Controller :
.controller('showNews', function($scope, $stateParams) {
$scope.indexVal = $stateParams.index; // getting index value passed from news.html
});
NewsViewer.html :
<div ng-controller="showNews">
<div>
<h3>{{News.Articles[indexVal].Title}}</h3>
<p>{{News.Articles[indexVal].Abstract}}</p>
<p>{{News.Articles[indexVal].Body}}</p>
</div>
</div>
Working demo : https://plnkr.co/edit/jfzm00ksZMAC8sGGUZSR?p=preview
I think this is what you want
NewsViewer.html
<div class="container-fluid">
<div class="row">
<div class="col-md-offset-1 col-md-6">
<div ng-controller="showNews">
<div>
<div>
<h3>{{selectedArticle.Title}}</h3>
<p>{{selectedArticle.Abstract}}</p>
<p>{{selectedArticle.Body}}</p>
</div>
<div class="comments">
<h4>Comments</h4>
<hr>
<div ng-repeat="comment in selectedArticle.Comments">
<p ng-repeat="(key, value) in comment">
<strong>{{key}}</strong>: {{value}}
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Please find the working solution below
https://embed.plnkr.co/rbNAcVGtBvTjl9VhfFAl/
Let me know, if you need further info. Enjoy :)
Edited
First of all we need to define two separate routes, one for News and one for Article
$routeProvider.when("/News", {
templateUrl: "News.html",
controller: "NewsContoller"
}).when("/NewsViewer", {
templateUrl: "NewsViewer.html",
controller: "NewsViewerController"
})
As you see, there are two separate controllers handling each route.
Then we need a value service to pass data between routes
angular.module('app').value('viewData', {})
After that on click of more link, set the value of viewData to that specific article and redirect to /NewsViewer route. And, on NewsViewerController retrieve that value from viewData and pass it to $scope.
Template: News.html
<div>
<div ng-repeat="NewsData in News.Articles">
<h3>{{NewsData.Title}}</h3>
<p>{{NewsData.Abstract}}</p>
<a href ng-click="showArticle(NewsData)">more</a>
</div>
</div>
Template: NewsViewer.html
<div>
<div>
<h3>{{Article.Title}}</h3>
<p>{{Article.Abstract}}</p>
<p>{{Article.Body}}</p>
</div>
<div class="comments">
<h4>Comments</h4>
<hr>
<p ng-repeat="(key, value) in Article.Comments[0]">
{{value}}
</p>
</div>
</div>
<a ng-href="#!/News">All News</a>
Controller: NewsController
angular.module('app').controller('NewsContoller', function($scope, $http, viewData, $location) {
$http({
method: 'GET',
url: 'News.json'
}).then(function success(response) {
$scope.News = response.data;
});
$scope.showArticle = function(article) {
viewData.article = article;
$location.path("/NewsViewer");
}
})
Controller: NewsViewerController
angular.module('app').controller('NewsViewerController', function($scope, viewData) {
$scope.Article = viewData.article;
})
Link of plunker is above in original answer.
I'm currently building my first single page app with angularJS. The variable information stored in my controller is not displaying on the page. After extensively trying to trouble-shoot this I am at a loss to why it isn't displaying.
<div ng-repeat="x in pers" class="person">
<div class="name">{{ pers.person }}</div>
<div class="out">Out</div>
<div class="in" >In</div>
<div class="onsite">On site</div>
<div class="notes">
<div class='n'></div>
<div class='dn'>Delete note</div>
<div class='an'>Add note</div>
</div>
My controller looks like this.
app.controller("MainController", ['$scope', function($scope) {
$scope.pers = [
{
person: 'Nick',
},
{
person: "Greg",
}];
}]);
The repeat function works as expected and two tables are formed, however both the divs with the class name are left without any text in them on the page. I have tried using ng-binding="pers.person" as well without any success.
Thanks in advance for any help you can offer with this issue I'm having.
it should be {{x.person}}
you are using ng-repeat of pers with the alias x
this is my first project on the ionic tecnology.Im still learning but Im stuck in one place.In js page, I creating repetitive page for listing films.I want to create one sample structure for ths page.And all films should be repetitive.
movie.picture, movie.title and **movie.rating I added these thigs but I cant get their values on the js and data service sides.Im confuse js and data service parts.I need basic examples :) how can I get those values?(by the way sorry for my bad language )
<ion-view view-title="films" ng-controller="filmlistcontroller">
<ion-content class="padding">
<div class="list" ng-repeat="movie in movies">
<br/>
<br/>
<a class="item item-thumbnail-left" href="#/tab/film">
<img ng-src="{{movie.picture}}" href="#/tab/film">
<h2>movie.title</h2>
<p>movie.rating</p>
</a>
</div>
</ion-content>
</ion-view>
the tutorial for this : Try This
index.html :
<ion-view view-title="films" ng-controller="filmlistcontroller">
<ion-content class="padding">
<div class="list" ng-repeat="movie in movies">
<br/>
<br/>
<a class="item item-thumbnail-left" href="#/tab/film">
<img ng-src="{{movie.picture}}" href="#/tab/film">
<h2>{{movie.title}}</h2>
<p>{{movie.rating}}</p>
</a>
</div>
</ion-content></ion-view>
filmlistcontroller :
.controller('filmlistcontroller', function($scope,$http ) { $http.get('URL')
.success(function (response) {
$scope.movies = response;
console.log("$scope.productInfo :"+JSON.stringify($scope.movies));
}).error(function(){
})});
hope this will help you.
In Angular,I am building a web app for an hotel that has different rooms. I want to be able to click on a tab in the navbar (or anywhere on the page.) and populate the html view with public data about the room that I have stored in the controller.
what is the best way to go about this? I am using ui-routing. I have yet to find an exhaustive answer on stack overflow.
Below is an example of what my app looks like.
This is my app.js
var appBB = angular
.module('appBB', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', MainRouter]);
function MainRouter(states, router) {
states
.state( 'home', {
url:'/',
templateUrl: 'home.html'
}).state( 'show',{
url:'/show',
templateUrl:'show.html'
});
router.otherwise('/');
}
This is my controller
appBB.controller("BBController", BBController());
function BBController() {
var self = this;
self.apartments = [
{
name: "apt1",
image: "imag1.jpg"
amenities: ["blablabal", "bhuhuih", "hvjf"]
},
{
name: "apt2",
image: "img2.jpg",
amenities: ["blablabla", "bkjhkg", "lkhug"]
},
{
name: "apt3",
image: "img3.jpg",
amenities: ["blablabla", "jgfkhgc","jgvkhg"]
}
]
}
This is an example of the view template that I want to fill:
<div ng-controller="BBController as bbs">
<div>
<h4>{{this should show the apt name}}</h4>
</div>
<div class="row">
<div class="col-sm-8">
<img ng-src="{{this should show the image of the apt that i clicked on}}" />
</div>
<div class="col-sm-4">
<ul>
<li ng-repeat="looping over the apt amenities">{{amenity}}</li> </ul>
</div>
</div>
</div>
Any help will be greatly appreciated.
What you are doing looks good but you need some improvement in it.I would suggest you to use $routeParams on Nav-bar clicks. something like:
<div ng-controller="BBController as bbs">
<div>
<h4>{{this should show the apt name}}</h4>
</div>
<div class="row">
<div class="col-sm-8">
<img ng-src="{{this should show the image of the apt that i clicked on}}" />
</div>
<div class="col-sm-4">
<ul>
<li ng-repeat="amemity in amenities">
<a ng-href="#amemityList/{{ amemity.id }}"> {{amemity.name}} </a>
</li>
</ul>
</div>
</div>
Now, you can use this amenity.id to pass to YourController and accordingly fetch respective view with all the info of that "clicked" amenity.id
.when('/amemityList/:navBar', {
templateUrl: "AmenityView.html",
controller: "YourController"
})
In this way, you will be able to use single view AmenityView.html and its info can be as per your amenity.id which has been passed to the controller like
var navBarSelection_id = $routeParams.navBar;
Maybe, you could add the info at the url like /show/apt1 and use apt1 to find the information on the controller.
Edit:
A little explanation: https://docs.angularjs.org/tutorial/step_07
Hi I am trying to retrieve data from the server using $http, and correct data is being retrieved from the service, the data is -
[{
"URL":"someimg.jpg",
"TITLE":"Test Demo",
"DATE_ADDED":"2014-02-08 00:46:00",
"SUMMARY":"this is summary"
}]
the template that I wrote is as follows -
<article class="span8" ng-controller="allBlogs">
<div ng-show="success">
<div ng-repeat="blog in blogs.data">
<div class="row">
<div class="span3">
<img ng-src="{{blog['URL']}}" alt="" />
</div>
<div class="span5" ng-repeat-end>
<h4>{{blog.TITLE}}</h4>
<p>{{blog.DATE_ADDED}}</p>
<p>{{blog.SUMMARY}}</p>
</div>
</div>
</div >
</div>
</article>
the controller for the above template is as follows -
pk.controller("allBlogs", function($scope, $http, BlogsHandler){
$scope.success = false;
(function(){
BlogsHandler.getAllBlogs().success(function(data){
console.log(data);
$scope.success = true;
$scope.blogs = data.data;
});
})();
});
I am trying to set the success as true when the service returns data and thus the remaining part of the template should run. But this is not happening. Is it not that any change to $scope variable is being watched by the framework itself?
Help needed. I even tried with ng-switch with no effect.
Thanks
You assign data.data to $scope.blogs, so you don't need to add .data before blogs again.
$scope.blogs = data.data;
So, try this:
<div ng-repeat="blog in blogs track by $index">
<div class="row">
<div class="span3">
<img ng-src="{{blog.URL}}" alt="" />
</div>
<div class="span5">
<h4>{{blog.TITLE}}</h4>
<p>{{blog.DATE_ADDED}}</p>
<p>{{blog.SUMMARY}}</p>
</div>
</div>
</div >