all arrays are not showing with angular - arrays

This is my controller that will fetch all notes for my main page. When I console.log($scope.allNotes) all my arrays are logged but when I render with my HTML only 1 array shows up
exports.allNotesController = function ($scope, $http, $notes) {
$notes.fetchNotes().then(function (result) {
var data = result.data
data.filter(function (notes) {
$scope.allnotes = notes.notes
console.log($scope.allnotes)
})
})
}
my HTML:
<section class="row all-notes">
<h1>All Notes</h1>
<div class="allNotes">
<ul ng-repeat="notes in allnotes">
<li>{{ notes }}</li>
</ul>
</div>
</section>
<a class="btn btn-default" href="#/login">Login</a>

I solved it in a very hacky way.
Heres my new controller
exports.allNotesController = function ($scope, $http, $notes) {
$notes.fetchNotes().then(function (result) {
$scope.allnotes = result.data
})
}
my HTML, this is where the magic happens. lol
<ul ng-repeat="notes in allnotes track by $index">
<li>{{ notes.notes.toString() }}</li> // i had no idea I can use toString() here
</ul>

Related

Angular - Filtering data based on bootstrap dropdown selection

I'm trying to filter a list based on a selection from a bootstrap dropdown, but cannot seem to get it to work. Here's my code:
<body>
<div class="toolbar-wrapper" >
<div class="btn-group container" role="group" ng-controller="filterController">
<div class="dropdown">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
{{filter}}
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="severity in severityLevels">{{severity}}</li>
</ul>
</div>
</div>
</div>
<div class="logMessages" ng-controller="logController">
<div >
<ul>
<li class="message" ng-repeat="logData in data | filter: filter | limitTo: quantity">
{{logData.timestamp}} : {{logData.severity}} : {{logData.message}}
</li>
</ul>
</div>
</div>
</body>
Javascript:
var app = angular.module('UnifyLog', []);
app.controller('filterController', function($scope) {
$scope.severityLevels = [
'ERROR',
'WARN',
'INFO',
'DEBUG'
];
$scope.filter = '';
$scope.resetFilter = function() {
$scope.filter = '';
};
$scope.changeSeverity = function(severity) {
$scope.filter = severity;
}
})
.controller('logController', function ($scope, $http) {
$http.get("https://clock/settings/get_log_messages", {}).then(
function (response) {
$scope.data = response.data;
},
function (response) {
console.log("fail:" + response);
}
);
$scope.quantity=100
});
I know you can use ng-model data binding with a select directive, but I want to use a bootstrap dropdown.
The code above is updating the scope.filter variable but the list of log messages does not filter.
The http request is getting back a json array with log data objects containing message, timestamp, and severity fields.
Try calling $scope.apply():
$scope.changeSeverity = function(severity) {
$scope.filter = severity;
$scope.apply()
}
Look here for more information, and consider another approach (use real data-binding instead of a custom callback): https://github.com/angular/angular.js/wiki/When-to-use-$scope.$apply()
I would create a customer severity filter like so:
.filter('severityFilter', function () {
return function (input, severity) {
var out = [];
if (input && input != []) {
angular.forEach(input, function (thing) {
if(thing.severity === severity){
out.push(thing);
}
});
}
return out;
}
})
Then apply it like this:
ng-repeat="logData in data | severityFilter: severity | limitTo: quantity">

How to bind and parse HTML content retrieved from database via Json

I'm using AngularJS 1.5.8.
I'm trying to bind {{card.reading}} in the view, but the data is rendered as text
html
<div ng-app="myApplication" ng-controller="postController as tarot">
<ul>
<li class="card" ng-repeat="card in tarot">
<img class="card" src="app/images/cards/{{card.value}}.png" alt="card.name">
<article>{{card.reading | unsafe}}</article>
</li>
</ul>
</div>`
JavaScript
var app = angular.module('myApplication', []);
app.controller('postController', function($scope, $http, $filter, $sce) {
$scope.$sce = $sce;
var url = './api.php/tarot';
$http.get(url).success(function(response) {
$scope.tarot = php_crud_api_transform(response).tarot;
});
});
app.filter('unsafe', function($sce){
return $sce.parseAsHtml;
});
exemple of JSON
{
"id":1,
"name": "Test",
"value": "1",
"reading": "<h2>Lorem Ipsum</h2><p>Lorem ipsum</p>"
}
Updating your HTML as such should do the trick..
<div ng-app="myApplication" ng-controller="postController as tarot">
<ul>
<li class="card" ng-repeat="card in tarot">
<img class="card" src="app/images/cards/{{card.value}}.png" alt="card.name">
<article ng-bind-html="card.reading"></article>
</li>
</ul>
</div>`
Thank you, it's solved now.
JavaScript
var app = angular.module('myApplication', ['ngSanitize'])
.controller('postController', ['$scope', '$http', '$sce',
function postController($scope, $http, $sce) {
var url = './api.php/tarot';
$http.get(url).success(function(response) {
$scope.tarot = php_crud_api_transform(response).tarot
});
$scope.explicitlyTrustedHtml = $sce.trustAsHtml();
}
]);
and the HTML as you suggested. :)
There is another solution . you can modify you code a little bit and it will work.
<div ng-app="myApplication" ng-controller="postController as tarot">
<ul>
<li class="card" ng-repeat="card in tarot">
<img class="card" src="app/images/cards/{{card.value}}.png" alt="card.name">
<article ng-bind-html="card.reading | unsafe"></article>
</li>
</ul>
</div>`
change your filter to ,
app.filter('unsafe', function($sce) {
return function(text) {
return $sce.trustAsHtml(text);
}
});
This will work.

Angular JS - Nested JSON Driving a Two Level Navigation - How to Alter scope from directive?

I'm new to Angular but enjoying getting to know it! I'm having no problem populating data but I'm stuck on this navigational problem.
I have a sidebar divided into two navigation s. Both are reading from nested JSON of 'areas' and 'reports'. The idea is that the currently selected/clicked item in the left hand list will populate the elements in the right hand list, according to its children in the JSON.
I've got the initial population working fine. It reads the 'areas' and assigns the active area, which displays the reports. I then have a directive which applies css classes on the click event, but how can I get it to also alter the active area?
I'm currently doing scope.activeArea = scope.areas[1];, but this does not work. The index is just there for development; that will be replaced by the index of the clicked element.
My HTML:
<div id="reports-subnav" ng-controller="reportAreasController">
<ul class="subnav-areas" >
<li ng-repeat="x in areas">
<a class="subnav-area-button" href="#" my-cool-directive>
<i class="{{ x.iconClass }}"></i>
</a>
</li>
</ul>
<ul id="nav-subsection" class="subnav-reports">
<li ng-repeat="r in activeArea.reports" id="{{ r.action }}" role="presentation"><span class="{{ r.iconClass }}"></span> {{ r.name }}</li>
</ul>
</div>
And Javascript:
var app = angular.module("focalWeb", []);
app.controller("reportAreasController", ['$scope','$http', function($scope, $http) {
$http.get('<?php echo SITE_ADDR; ?>/data/reportAreas.json').success (function(data){
$scope.areas = data.areas;
$scope.activeArea = $scope.areas[0];
});
}] );
app.directive("myCoolDirective", function() {
return {
restrict: "A",
link: function(scope, elem, attrs) {
$(elem).click(function() {
//var target = $(elem).next(".panel-collapse");
//target.hasClass("collapse") ? target.collapse("show") : target.collapse("hide");
$('.subnav-areas li').removeClass('active');
$(this).parent().addClass('active');
scope.activeArea = scope.areas[1];
});
}
}
});
Thanks!
Edit
Thanks to charlietfl's guidance my code now looks like this:
HTML
<div id="reports-subnav" ng-controller="reportAreasController">
<ul class="subnav-areas" >
<li class="subnav-area" ng-repeat="x in areas">
<a class="subnav-area-button" href="#" ng-click="showReports($event, x.id)">
<i class="{{ x.iconClass }}"></i>
</a>
</li>
</ul>
<ul id="nav-subsection" class="subnav-reports">
<li ng-repeat="r in activeArea.reports" id="{{ r.action }}" role="presentation"><span class="{{ r.iconClass }}"></span> {{ r.name }}</li>
</ul>
</div>
JS
var app = angular.module("focalWeb", []);
app.controller("reportAreasController", ['$scope','$http', function($scope, $http) {
$http.get('<?php echo SITE_ADDR; ?>/data/reportAreas.json').success (function(data){
$scope.areas = data.areas;
$scope.activeArea = $scope.areas[0];
$scope.showReports = function($event, index) {
$scope.activeArea = $scope.areas[index -1];
var theLi = angular.element($event.currentTarget).parent();
theLi.parent().find('li').removeClass('active');
theLi.addClass('active');
}
});
}] );
Edit 2
HTML
<div id="reports-subnav" ng-controller="reportAreasController">
<ul class="subnav-areas" >
<li class="subnav-area" ng-repeat="x in areas" ng-class="{active: x==activeArea}">
<a class="subnav-area-button" href="#" ng-click="showReports($event, x)">
<i class="{{ x.iconClass }}"></i>
</a>
</li>
</ul>
<ul id="nav-subsection" class="subnav-reports">
<li ng-repeat="r in activeArea.reports" id="{{ r.action }}" role="presentation"><span class="{{ r.iconClass }}"></span> {{ r.name }}</li>
</ul>
</div>
JS
var app = angular.module("focalWeb", []);
app.controller("reportAreasController", ['$scope','$http', function($scope, $http) {
$http.get('<?php echo SITE_ADDR; ?>/data/reportAreas.json').success (function(data){
$scope.areas = data.areas;
$scope.activeArea = $scope.areas[0];
$scope.showReports = function($event, item) {
$scope.activeArea = item;
}
});
}] );
Thanks again charlietfl!

Compare objects in angularjs

What I'm trying to achieve is that if a Post contains comments, it should display the comments. I tried the angular.equals, which either doesn't work or I am not familiar on how to use it right?
Here's the Controller for both Post and Comment.
var PostController = function ($scope, $location, Post, Comment) {
$scope.search = function () {
Post.query({
offset: $scope.offset,
limit: $scope.limit
},
function (data) {
$scope.more = data.length === 20;
$scope.posts = $scope.posts.concat(data);
});
};
$scope.searchComments = function () {
Comment.query({
},
function (data) {
$scope.comments = data;
});
};
$scope.showComment = function () {
angular.equals(Post, Comment);
}
}
And here's from the view:
<ul class="posts">
<li ng-repeat="post in posts">
<div class="post-info">
<h1>{{post.title}}</h1>
<div class="right-section">
<div class="edit-post-button right">Edit</div>
<span class="reputation right">{{post.reputation}}</span>
</div>
</div>
<br />
<div class="post-box">
<p>
{{post.content}}
</p>
</div>
<br />
<ul>
<li ng-repeat="comment in comments" ng-show="showComment()">
{{comment.content}}
</li>
</ul>
</li>
</ul>
Maybe this could be done in the back-end? I am not sure?
It seems like you want to filter the comments to a particaular post. As you have said in comments, the Comment resource has a pid that ties it to a particular post.
The best way to accomplish the filtering is with an angular filter.
In this way, you don't need to compare anything with equals, you can just filter the comments in the markup:
<ul>
<li ng-repeat="comment in comments | filter:{ pid: post.id }">
{{comment.content}}
</li>
</ul>

Angularjs losing scope in same line ng-repeat

I'm having trouble replacing the {{path}} within the template tag in the ng-include. If I put the tag inside the template anywhere else works perfectly, however I need to work within the include-ng to get the base path. Anyone have an idea.
Html with MVC
<div ng-controller='menuCtrl'>
<nav id="menu">
<ul>
<li ng-repeat="item in itens" ng-include="'#(ViewBag.path)Areas/System/scripts/templates/menu.html'" repeat-done></li>
</ul>
</nav>
</div>
App.js
var myApp = angular.module('mobsupplyApp', []).directive('repeatDone', function () {
return function (scope) {
if (scope.$last === true) {
setTimeout(function () {
$("#menu").jarvismenu();
});
}
};
});
myApp.controller('menuCtrl', ['$scope', '$http', function ($scope, $http) {
$http.get(path + "api/menu").success(function (data, status) {
$scope.itens = data;
$scope.path = path;
});
}]);
Template.html
<i class="fa fa-lg fa-fw {{ item.image }}"></i> <span class="menu-item-parent">{{ item.description }}</span>
<ul ng-if="item.itens">
<li ng-repeat="item in item.itens" ng-include="'{{ path }}Areas/System/scripts/templates/menu.html'"></li>
</ul>

Resources