Trouble with ng-repeat - javascript

I'm trying to get to grips with AngularJS and had this working to echo individual things from a controller, but when I tried to incorporate a loop with ng-repeat all I get is {{tasks.title}} flashing onscreen for a second, then a blank empty div.
Any examples I've looked up seem a little different and I've tried a few ways, can anyone see where I'm going wrong?
Controller:
app.controller('MainController', ['$scope', function($scope) {
$scope.tasklist = {
tasks: [{
title: 'Wash Dog'
}, {
title: 'Email Joe'
}]};
}
]);
HTML:
<section class="panel">
<div ng-controller="MainController">
<div class="thumbnail" ng-repeat="tasks in tasklist">
<p>{{ tasks.title }}</p>
</div>
</div>
</section>

You are accessing the property tasklist not the actual tasks. It should be tasklist.tasks
<section class="panel">
<div ng-controller="MainController">
<div class="thumbnail" ng-repeat="tasks in tasklist.tasks">
<p>{{ tasks.title }}</p>
</div>
</div>
</section>
Another way would be to remove the tasks property:
app.controller('MainController', ['$scope', function($scope) {
$scope.tasklist = [
{
title: 'Wash Dog'
},
{
title: 'Email Joe'
}
];
}]);

Related

Data does not show in view using AngularJS directives

I trying to use directives to show controller data in the my view but nothing displays and there are no errors in the console. I am able to log the data but the data will not show in view. Am I using directives the correct way? How do I show the data in the view? Thank you.
index.html
<body ng-app="GameboardApp">
<div class="header">
<h1 class="logo">GameBoard</h1>
</div>
<div class="main" ng-controller="ScoreController">
<div class="container">
<div class="row" >
<game ng-repeat="score in scores" info="score"></game>
</div>
</div>
</div>
<!-- Modules -->
<script src="js/app.js"></script>
<!-- Controllers -->
<script src="js/controllers/ScoreController.js"></script>
<!-- Directives -->
<script src="js/directives/game.js"></script>
App.js
var app = angular.module('GameboardApp', []);
Controllers
ScoreController:
app.controller('ScoreController', ['$scope', function($scope) {
$scope.scores = [
{
datetime: 1420848000000,
visitor_team: {
city: "Charlotte",
name: "Hornets"
},
home_team: {
city: "New York",
name: "Knicks"
},
period: "Final",
visitor_score: 110,
home_score: 82
},,
...
},
{
datetime: 1420848000000,
visitor_team: {
city: "Orlando",
name: "Magic"
},
home_team: {
city: "Portland",
name: "Trail Blazers"
},
period: "First Quarter",
visitor_score: 13,
home_score: 26
}
];
console.log($scope.scores);
}]);
directives
game.js
app.directive('game', function() {
return {
restrict: 'E',
score: {
info: '='
},
templateUrl: 'js/directives/game.html'
}
})
game.html
<div class="col-sm-4">
<div class="row scorecard">
<p class="period">{{info.period}}</p>
<div class="visitor col-xs-4">
<h2 class="visitor-score">{{info.visitor_score}}</h2>
<h3>
<span class="visitor-city">{{info.visitor_team.city}}</span><br/>
<span class="visitor-name">{{info.visitor_team.name}}</span>
</h3>
</div>
<div class="dash col-xs-3">
<h2>-</h2>
</div>
<div class="home col-xs-4">
<h2 class="home-score">{{info.home_score}}</h2>
<h3>
<span class="home-city">{{info.home_team.city}}</span><br/>
<span class="home-name">{{info.home_team.name}}</span>
</h3>
</div>
</div>
In game.js file, where you have created the directive, you have misspelled the field name. It should be scope not score.

AngularJS - Dynamic Checkboxes to hide/show Divs

I'm new to front-end web development. I am creating checkboxes dynamically using AngularJS.
<div ng-repeat="x in Brands" style="margin-left: 20px">
<input type="checkbox" ng-model="newObject[x.product_brand]">
<label> {{ x.product_brand }} </label>
</div>
Following the methods given on the links below, I want to hide/show divs using
using the dynamically created checkboxes.
Dynamic ng-model
ng-show
Here's the code-
<div class="item panel panel-default" ng-repeat="x in Brands" ng-show="newObject[x.product_brand]">
<div class="panel-heading">
{{x.product_brand}}
</div>
<div class="panel-body">
</div>
</div>
Controller-
app.controller('BrandController', function($scope, $http) {
getProductsInfo();
function getProductsInfo() {
$http.get("sql.php").success(function(data) {
$scope.Brands = data;
});
};
});
But it is not working. Checking/Unchecking the checkboxes does nothing.
I think you need something like this runnable fiddle. This kind of handle is easy to manage with AngularJS. Welcome =) !!! Please note: The $timeout is to simulate your async $http request - its not a part of the solution.
View
<div ng-controller="MyCtrl">
<div ng-repeat="x in Brands" style="margin-left: 20px">
<input type="checkbox" ng-model="x.active">
<label> {{ x.product_brand }} </label>
</div>
<div class="item panel panel-default" ng-repeat="x in Brands" ng-show="x.active">
<div class="panel-heading">
{{x.product_brand}}
</div>
<div class="panel-body">
</div>
</div>
</div>
AngularJS demo application
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function ($scope, $timeout) {
$scope.Brands = [];
init();
function init () {
$timeout(function () {
$scope.Brands = [{
product_brand: 'brand 1'
},{
product_brand: 'brand 2'
},{
product_brand: 'brand 3'
},{
product_brand: 'brand 4'
}];
});
}
});
Probably it is not working because you never defined newObject on the $scope. So actually you are trying to access undefined[x.product_brand].
Something like $scope.newObject = {}; in your Controller should do the trick.

AngularJS expression doesn't work in a different view

So I have this problem with creating a new view. The routeing works just fine because it shows the required HTML perfectly, but the expressions which worked just fine in the main view don't show up in the new.
<a href="#/view/{{todo.id}}" id="super" ng-repeat="todo in todos | filter: search">
<div id="main" ng-class="{'done': todo.done}">
<input type="checkbox" ng-model="todo.done" />
<span>{{todo.title}}</span>
<button id="info">i</button>
<div class="inf">
<span>Prioritás: {{todo.priority}}</span>
</div>
<div class="inf" id="sec">
<span>Határidő: {{todo.deadLine | date: "yyyy. MMMM. dd"}}</span>
</div>
</div>
</a>
These are the expressions in the main view, they work like a charm.
myTodoList.config(['$routeProvider', function($routeProvider, $locationProvider) {
$routeProvider
.when('', {
templateUrl: 'index.html',
controller: "mainController"
})
.when('/view/:id', {
templateUrl: 'view.html',
controller: "mainController"
}).otherwise({
redirectTo: ''
});
This is the routeing part, this is working.
<div id="mainContent">Master Detail
<div ng-controller="mainController" ng-view></div>
</div>
This is the div where the new view goes.
<div>
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p></div>
And this is the view.html. The third expression is working, so I have the problem with de other two expressions. I think I messed up this because I can't reach the data I want. todo.id and todo.title are data created by a function in real time.
$scope.addTodo = function(title, priority, deadLine, id) {
$scope.todos.push({
'id': lastId,
'title': $scope.newTodo,
'done': false,
'priority': $scope.newPriority,
'deadLine': $scope.newDeadLine
});
$scope.newTodo = ''
$scope.newPriority = ''
$scope.newDeadLine = ''
lastId++;
}
This is the function I am using. I hope I described the problem well.
Are you using ng-repeat in your new view ?
<div>
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p></div>
Your Scope variable name is $socpe.todos but here you are trying to access todo make sure if you are inside the ng-repeat if this is not your problem then share your full code on fiddle or codepen.
Just like Jeyenthaaran Nanjappan said, i think your div should look like this:
<div ng-repeat="todo in todos">
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p>
</div>
Okay, I solved the problem. I needed to separate the different objects. So I made a function.
$scope.currentTodo = $scope.todos[0];
$scope.selectTodo = function(todo) {
$scope.currentTodo = todo;
}
I made a div and called this function with it.
<div ng-click="selectTodo(todo);" id="super" ng-repeat="todo in todos | filter: search">
And the problematic div now looks like this.
<div id="mainContent">Master Detail
<div>
<p>Should be the ID: {{currentTodo.id}}</p>
<p> should be the title: {{currentTodo.title}}</p>
</div>
</div>
Thank you for your help! I think both of you helped me through this problem.
Some issues in the nesting of the div and html. Change this:
<div id="mainContent">Master Detail
<div ng-repeat="todo in todos" ng-controller="mainController" ng-view></div>
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p>
</div>
to this:
<div id="mainContent">Master Detail
<div ng-repeat="todo in todos" ng-controller="mainController">
<p>Should be the ID: {{todo.id}}</p>
<p> should be the title: {{todo.title}}</p>
<p> this works: {{1+2}}</p>
</div>
</div>

Get single post id from json file in AngularJS

This is maybe real easy, don´t know. But i´ve only done this with a node/express backend.
But not quite surt how to do this, only with frontend and a json file, where my data is.
Right now it shows a list of all my posts, but i want to get the unique post:id when clicking on a button.
A simple posts.json file:
[{
id: 1,
title: 'Simple title1',
content: 'Sample content...',
permalink: 'simple-title1',
author: 'Peter',
datePublished: '2012-04-04'
}, {
id: 2,
title: 'Simple title2',
content: 'Sample content...',
permalink: 'simple-title2',
author: 'Peter',
datePublished: '2012-05-04'
}, {
id: 3,
title: 'Simple title3',
content: 'Sample content...',
permalink: 'simple-title3',
author: 'Thomas',
datePublished: '2012-06-04'
}]
Here is my app.js file:
var routerApp = angular.module('routerApp', ['ui.router']);
routerApp.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/posts',
templateUrl: 'partial-home.html',
controller: function($scope, $http){
$http.get('posts.json')
.success(function(data){
$scope.posts = data;
});
}
})
.state('viewdetails',{
url:'/posts/:id/:permalink',
templateUrl: 'view_details.html',
controller: function($scope, $http){
$http.get('source.json')
//get a single post here???
} }
And some of the code in my partial-home.html
<div class="row" style="margin-left:50px">
<!--row left-->
<div class="col-xs-8 col-sm-4 col-md-3 col-lg-5 box-background" ng-repeat="post in posts">
<!--column 1 left-->
<div class="col-md-4 img-space">
<img class="img-circle" alt="Bootstrap Image Preview" src="{{prov.picture}}" /></div>
<div class="col-md-4">
<h4>{{post.author}}</h4>
<p class="text-grey">
{{post.content}}
</p>
</div>
<a ui-sref="posts/:id" class="btn btn-primary btn-color" style="width:100%">View details</a>
</div>
<!--end column 1 left-->
</div>
<!--end row left-->
I know this isn´t in a mvc pattern, but just want to do it really simple.
Have only done this before with a mongoose, node backend. So hope for some ideas help.
Thanks.
You would use $routeParams to get the id from your route and then use that as a variable in your $http request url.
When fetching the same sourse.json file you can use that id to only assign the correct post to your view variable
https://docs.angularjs.org/api/ngRoute/service/$routeParams

Change background image on hover with AngularJS

I have a scope of 's with their background images, but I can't figure out how to make them change. I tried several variants, but none of them has passed. Here's the code:
<div ng-controller="mainController" class="main">
<div ng-repeat="land in lands" class="col-md-9" ng-style="{ 'background-image': 'url({{ land.cover }})'}">
<p>{{ land.name }}</p>
</div>
</div>
Javascript:
app.controller('mainController', ['$scope', function($scope) {
$scope.lands = [
{
cover: 'img/norway.jpg',
cover1: 'img/norway1.jpg',
name: 'Norway'
},
{
cover: 'img/sweden.jpg',
cover1: 'img/sweden1.jpg',
name: 'Sweden'
},
{
cover: 'img/denmark.jpg',
name: 'Danmark'
},
{
cover: 'img/iceland.jpg',
name: 'Iceland',
},
{
cover: 'img/finland.jpg',
name: 'Finland'
},
{
cover: 'img/estonia.jpg',
name: 'Estonia'
}
];
}]);
You can't use interpolation tags in the expression context. Should be:
<div ng-controller="mainController" class="main">
<div ng-repeat="land in lands" class="col-md-9"
ng-init="coverImage = land.cover"
ng-mouseover="coverImage = land.cover"
ng-mouseout="coverImage = land.cover1"
ng-style="{ 'background-image': 'url(' + coverImage + ')' }">
<p>{{ land.name }}</p>
</div>
</div>
Since you're trying to respond to the DOM, the angular way of doing this would be to create a directive.
Working code is available here. The summary of the solution is this:
Your DOM will change to this:
<div ng-controller="MainController as ctrl">
<div ng-repeat="land in ctrl.lands" hover-bg-change default-bg="land.cover" hover-bg="land.cover1" class='tile'>
<p>{{ land.name }}</p>
</div>
</div>
The directive will look like this:
app.directive('hoverBgChange', ['$parse', function ($parse)
{
return {
restrict: 'A',
link: function (scope, $el, attrs)
{
var defaultBg = $parse(attrs.defaultBg)(scope);
var hoverBg = $parse(attrs.hoverBg)(scope);
$el.css('background-image', 'url('+defaultBg+')');
$el.on('mouseover', function ()
{
$el.css('background-image', 'url('+hoverBg+')');
})
.on('mouseout', function ()
{
$el.css('background-image', 'url('+defaultBg+')');
});
}
}
}])
You can't make it work in one go.
My solution would be
define css as
.hover-out{
background-image: url('img/norway.jpg');
}
.hover-in{
background-image: url('img/norway1.jpg');
}
In markup
<div ng-controller="mainController" class="main">
<div ng-repeat="land in lands" class="col-md-9" ng-class="{'hover-out':hoverOut[$index], 'hover-in':!hoverOut[$index]}" ng-mouseover="hoverOut[$index] = false" ng-mouseleave="hoverOut[$index] = true">
<p>{{ land.name }}</p>
</div>
</div>

Categories