Order JSON data in Angular (Ionic) - angularjs

I need help with ordering JSON in ng-repeat. I want to order my data by item.id (from highest to lowest). I tried many tips that are over internet but maybe I'm just doing something wrong because none of them are working for me... My code:
$http.get('http://jastrzebieonline.pl/drogi/data/najnowsze.php')
.success(function(res){
$scope.news = res;
console.log("Ok");
})
.error(function(data, status) {
console.log("Error");
})
<div ng-repeat="item in news">
<a href="{{ item.id }}">
<img src="{{ item.image }}">
<h2>{{ item.title }}</h2>
<p>{{ item.date }}</p>
<p>{{ item.text }}</p>
</div>
</a>
</div>

You can use the orderBy filter:
<div ng-repeat="item in news | orderBy:'id'">
<a href="{{ item.id }}">
<img src="{{ item.image }}">
<h2>{{ item.title }}</h2>
<p>{{ item.date }}</p>
<p>{{ item.text }}</p>
</div>
</a>
</div>

You can use the "orderBy" filter to do the job.
By the way, you should use 'ngHref' and 'ngSrc' directives instead of the original 'href' and 'src' attribute.
<div ng-repeat="item in news | orderBy:'id':true">
<a ng-href="{{ item.id }}">
<img ng-src="{{ item.image }}">
<h2>{{ item.title }}</h2>
<p>{{ item.date }}</p>
<p>{{ item.text }}</p>
</div>
</a>
</div>
references:
https://docs.angularjs.org/api/ng/filter/orderBy
https://docs.angularjs.org/guide/filter

Related

Why does $parent.$index equals $index?

In AngularJS 1.6.3 it is basically possible to nest ng-repeat.
I have determined, that in two nested ng-repeat the $parent.$index equals $index.
The following code is given:
<div ng-repeat="category in :: $ctrl.categories">
<span id="category-{{ $index }}">
{{ :: category.name }}
</span>
<ul>
<li ng-repeat="data in :: category.links"
id="link-{{ $parent.$index }}-{{ $index }}">
{{ :: data.name }}
</li>
</ul>
</div>
Expected resulting ID's for LI:
<div>
<span id="category-0">CatA</span>
<ul>
<li id="link-0-0">[..]</li>
<li id="link-0-1">[..]</li>
<li id="link-0-2">[..]</li>
</ul>
</div>
<div>
<span id="category-1">CatB</span>
<ul>
<li id="link-1-0">[..]</li>
<li id="link-1-1">[..]</li>
</ul>
</div>
Actual resulting ID's for LI:
<div>
<span id="category-0">CatA</span>
<ul>
<li id="link-0-0">[..]</li>
<li id="link-1-1">[..]</li>
<li id="link-2-2">[..]</li>
</ul>
</div>
<div>
<span id="category-1">CatB</span>
<ul>
<li id="link-0-0">[..]</li>
<li id="link-1-1">[..]</li>
</ul>
</div>
Can someone confirm this behaviour? Or did I miss something?
Working as expected.
angular.module('test', []).controller('Test', Test);
function Test($scope) {
var $ctrl = this;
$ctrl.categories = [
{
name: 'cat1',
links: [{name: 'l1'}, {name: 'l2'}, {name: 'l3'}]
},
{
name: 'cat2',
links: [{name: 'l4'}, {name: 'l5'}]
}
]
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.3/angular.min.js"></script>
<div ng-app='test' ng-controller='Test as $ctrl'>
<div ng-repeat="category in :: $ctrl.categories">
<span id="category-{{ $index }}">
{{ :: category.name }}
</span>
<ul>
<li ng-repeat="data in :: category.links"
id="link-{{ $parent.$index }}-{{ $index }}">
{{ :: data.name }}
</li>
</ul>
</div>
</div>
You probably have some scope generating elements surrounding your child layer e.g. ng-if, ng-repeat, ng-switch. In this case you'll need to add more layers of $parent

Using Angular $first and $last outside of ng-repeat

I have this code:
<main class="gallery">
<nav class="gallery-list-thumbs">
<ul>
<li ng-click="showLarge($event); modalShow()" ng-repeat="photo in photos | filter:{'section': section }">
<img data-ref="ref-{{ photo.id }}" data-orientation="{{ photo.orientation }}" class="photo-small" ng-src="photos/{{ photo.section }}/th/{{ photo.src }}">
</li>
</ul>
</nav>
<section class="gallery-item" ng-hide="modalHidden">
<h1 ng-model="section">{{ section }}</h1>
<div class="photo-container">
<div class="modal-close" ng-click="modalShow()"></div>
<div class="modal-prev"></div>
<div class="modal-next"></div>
<img data-photoref="ref-{{ photo.id }}" ng-repeat="photo in photos | filter:{'section': section }" class="photo-large below orientation-{{ photo.orientation }}" ng-class="{'above':$first}" ng-src="photos/{{ section }}/{{ photo.src }}">
</div>
</section>
</main>
What I hope to achieve, is to hide the modal-prev when the user click on the first li in gallery-list-thumbs and the same thing with modal-next on the last li.
So far, using $index, it's fairly easy since I can target it by a scope change, but how do I get the last element when there's a different amount of images per galleries? It would be easier if the next and prev arrows were inside the ng-repeat since I could use $first and $last, but I don't want to have to include them in.
OK, I was able to find it by myself.
The solution was to change a scope on $first and last and then add a ng-show and ng-hide depending on the scope value.
Here's the code if anyone has this kind of issue:
<main class="gallery">
<nav class="gallery-list-thumbs">
<ul>
<li ng-click="showLarge($event); modalShow();setPosition('inbetween'); $first && setPosition('first') ; $last && setPosition('last')" ng-repeat="photo in photos | filter:{'section': section }">
<img data-ref="ref-{{ photo.id }}" data-orientation="{{ photo.orientation }}" class="photo-small" ng-src="photos/{{ photo.section }}/th/{{ photo.src }}">
</li>
</ul>
</nav>
<section class="gallery-item" ng-hide="modalHidden">
<h1 ng-model="section">{{ section }}</h1>
<div class="photo-container">
<div class="modal-close" ng-click="modalShow()"></div>
<div class="modal-prev" ng-hide="currentOrder == 'first';">{{ currentOrder }}</div>
<div class="modal-next" ng-hide="currentOrder == 'last';">{{ currentOrder }}</div>
<img data-photoref="ref-{{ photo.id }}" ng-repeat="photo in photos | filter:{'section': section }" class="photo-large below orientation-{{ photo.orientation }}" ng-class="{'above':$first}" ng-src="photos/{{ section }}/{{ photo.src }}">
</div>
</section>
</main>

Accessing a nested ng-repeat variable

This is what I have so far:
<div ng-repeat="storeSection in main.foodBySection" ng-show="main.sortBy === 'storeSection'">
<h4>{{ storeSection.category }}</h4>
<div ng-repeat="ingredient in main.ingredients | orderBy: 'name'"
ng-if="ingredient.storeSection === {{ storeSection.category }}">
<p><input type="checkbox" ng-model="ingredient.added"/> {{ ingredient.name }} <span
class="ingredient-source">- {{ ingredient.source }}</span></p>
</div>
</div>
Basically, I only want to display the items in main.ingredients that have the same category as the header, but I cannot access {{ storeSection.category }} once I use a new ng-repeat. Any ideas?
<div ng-repeat="storeSection in main.foodBySection" ng-show="main.sortBy === 'storeSection'">
<h4>{{ storeSection.category }}</h4>
<div ng-repeat="ingredient in main.ingredients | orderBy: 'name'"
ng-if="ingredient.storeSection === storeSection.category">
<p><input type="checkbox" ng-model="ingredient.added"/> {{ ingredient.name }} <span
class="ingredient-source">- {{ ingredient.source }}</span></p>
</div>
</div>
<div ng-repeat="storeSection in main.foodBySection" ng-show="main.sortBy === 'storeSection'">
<h4>{{ storeSection.category }}</h4>
<div ng-repeat="ingredient in main.ingredients | orderBy: 'name'"
ng-if="ingredient.storeSection === storeSection.category ">
<p><input type="checkbox" ng-model="ingredient.added"/> {{ ingredient.name }} <span
class="ingredient-source">- {{ ingredient.source }}</span></p>
</div>
</div>
Don't interpolate storeSection.category, ng-if works with angular-expressions just like the left-hand operandingredient.storeSection is getting evaluated by it
As pointed out in another answers, the cause of the problem is that you're using interpolation in your ngIf directive, which one works with angular-expressions.
Tips:
Use preferably ngIf instead of ngShow(in your first <div>).
I also recommend you to use the native filter instead of this check using ngIf(in ngRepeat) and to use the ngRepeat#special-repeats.
So you can have something like this:
<div ng-repeat-start="storeSection in main.foodBySection" ng-if="main.sortBy === 'storeSection'">
<h4 ng-bind="storeSection.category"></h4>
</div>
<div ng-repeat-end ng-repeat="ingredient in main.ingredients | filter: { storeSection: storeSection.category } | orderBy: 'name'">
<p>
<input type="checkbox" ng-model="ingredient.added" /> {{ ingredient.name }} <span class="ingredient-source">- {{ ingredient.source }}</span></p>
</div>

AngularJS loop show the same image

In my project I need to show for each element its image.
This is my html:
<div ng-repeat="event in events.events" class="event show-place" data-id="#{{ event.id }}"
ng-mouseenter="selectEvent(event)">
<div class="cover-events">
<img width="100%" height="100%"
ng-src="#{{ selectedEvent.place.image | addFullPathToImage }}"
alt="#{{ selectedEvent.place.name }}"
>
<div class="user-info">
<a href="#{{ event.created_by.profileSlug }}">
<immagine-profilo hashid="#{{ event.created_by.hashid }}"
username="#{{ event.created_by.profile.username }}"
photo="#{{ event.created_by.profile.photo }}"></immagine-profilo>
<div class="user-event" ng-bind="event.created_by.profile.username"></div>
<rating class="user-experience" stars="#{{ event.created_by.level }}"
icon="star"></rating>
</a>
</div>
</div>
<div class="info-event">
<div vertilize class="content-info">
<div class="title-place">
<h2 ng-bind="event.place.name"></h2>
</div>
<div class="date-time">
#{{ event.unix_date | formatDate }} | #{{ event.time_start }}
</div>
<div class="event-feature">
<div class="category pull-left">
<img ng-src="#{{ event.category.icon | addFullPathToIcon }}"
alt="#{{ event.category.name }}">
<span ng-bind="event.category.name"></span>
</div>
<div class="difficulty pull-left">
<rating class="difficulty-bar" stars="#{{ event.difficulty_level }}"
icon="circle"></rating>
<span>
{{ trans('frontend/events/events.strings.difficulty') }}
</span>
</div>
<div class="participants pull-left">
<div class="speech-bubble speech-bubble-bottom">
#{{ event.participants_count }}
</div>
<span>{{ trans('frontend/events/events.strings.participants') }}</span>
</div>
</div>
</div>
<a class="link-with-arrow"
href="{{ localeRoute('events.event', [null, null])}}/#{{ event.slug }}/#{{ event.id }}">
{{ trans('frontend/pages/place.sidebar.links.read_more') }}
</a>
</div>
the image code is this:
<img width="100%" height="100%"
ng-src="#{{ selectedEvent.place.image | addFullPathToImage }}"
alt="#{{ selectedEvent.place.name }}">
and this is the filter:
app.filter('addFullPathToIcon', function () {
return function (text) {
return window.paths.categoriesPath + "/" + text;
}
});
When I run the code, the same image is shown for each event, if I click on one of it, the images will change and show the second image for every event.
Someone can help me to see the error?
It looks to me like there's only one "selectedEvent", and it is defined on ng-mouseenter. Perhaps you want
<img width="100%" height="100%"
ng-src="#{{ event.place.image | addFullPathToImage }}"
alt="#{{ event.place.name }}">
instead inside your ng-repeat if you don't want all the images to change with the event that is selected...

how i get total of item in ng-repeat

I'm trying to get the overall number of items in each iteration.my code is this
<ul class="phones">
<li ng-repeat="phone in phones | filter:query | orderBy:orderProp"
ng-init="index()" class="thumbnail">
<a href="#/phones/{{phone.id}}" class="thumb">
<img ng-src="{{phone.imageUrl}}">
</a>
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
<div>
{{ total }}
</div>
Controller
phonecatApp.controller('PhoneListCtrl', function($scope, $http)
{
$scope.total =0;
$scope.index =function()
{
$scope.total ++;
}
}
By dynamic you mean total no of phones currently displayed after filter is applied.
<ul class="phones">
<li ng-repeat="phone in filtered = (phones | filter:query | orderBy:orderProp)"
ng-init="index()" class="thumbnail">
<a href="#/phones/{{phone.id}}" class="thumb">
<img ng-src="{{phone.imageUrl}}">
</a>
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
<div>
{{ filtered.length }}
</div>
To make more sense of data (Bonus Tip :) )
<div ng-show="query">
<ng-pluralize count="filtered.length" when="{'0': ' No search result ', 'one': ' 1 search result ', 'other': ' {} search results '}"></ng-pluralize> for {{query}}
</div>
Are you trying to get total number of phones?
you can simply use length property in expression instead {{ total }}
{{ phones.length }}

Resources