Angular.js click through to item details page - javascript

I'm quire new to Angular so I apologise if this has already been answered but I just couldn't figure it out when I see other uses for it.
I am using a REST API to simply fetch some news articles from an external URL and print them out nicely on a news listing page.
Link for results
(You can see the output of the JSON in the console)
The JSON that is returned looks like this (just showing one set):
[
{
"author":"Napier Lopez",
"title":"Report: First real Samsung Galaxy S8 photo and release date leaked",
"description":"Ever-reliable leaker Evan Blass of Venture Beat has just given us our best look at Samsung’s Galaxy S8 yet. The report confirms several of the details we’ve already learned about the device, as well as providing an announcement and release date. Blass confirms that the devices are foregoing the front fingerprint scanner for one place on …",
"url":"https://thenextweb.com/mobile/2017/01/26/report-first-real-samsung-galaxy-s8-photo-release-date-leaked/",
"urlToImage":"https://cdn3.tnwcdn.com/wp-content/blogs.dir/1/files/2017/01/Samsung-Galaxy-S8-Blur-not-real.jpg",
"publishedAt":"2017-01-26T22:13:13Z"
} ...
]
Here is my how I've printed out each news article:
app.js:
/* Newsfeed API Call */
var app = angular.module('newsFeed', [])
.controller('Newsfeed', function($scope, $http) {
$http.get('https://newsapi.org/v1/articles?source=the-next-web&sortBy=latest&apiKey=6ddf8d3cc8a54cc0abf89ad7d685da54').
then(function(response) {
$scope.news = response.data;
});
});
news-listing.html:
<div class="container" ng-controller="Newsfeed">
<br/>
<form>
<div class="col-md-6">
<h2>Newsfeed</h2>
<br/>
<div class="form-group">
<input type="text" class="form-control" ng-model="searchText" name="search-news" id="search-news" placeholder="Search for news">
</div>
<div class="form-group">
<select class="custom-select" ng-model="selectedAuthor" ng-options="n.author for n in news.articles | unique: 'author'">
<option ng-click="selectedAuthor = undefined" value="">Filter by Author</option>
</select>
</div>
</div>
</form>
<div>
<div class="card" style="width: 20rem;" ng-repeat="n in news.articles | filter:searchText | filter:selectedAuthor">
<img class="card-img-top img-responsive" src="{{n.urlToImage}}" alt="Card image cap">
<div class="card-block">
<h4 class="card-title">{{n.title | cut:true:50:' ...'}}</h4>
<p class="card-text"> {{n.author}} <small>on {{ formatDate(n.publishedAt) | date:'MM/dd/yyyy'}}</small> </p>
<p class="card-text"> {{n.description | cut:true:100:' ...'}}</p>
<a class="btn btn-primary" href="#" role="button"><i class="fa fa-thumbs-up" aria-hidden="true"></i></a>
<a class="btn btn-danger" href="#" role="button"><i class="fa fa-thumbs-down" aria-hidden="true"></i></a>
</div>
</div>
</div>
</div>
What I want is that for each news article in the news-listing I can click on it to see more details, so I would have an articles-details page that would take some sort of unique identifier and use that to pull out all of the data.
How can I achieve this baring in mind that the response in the JSON for the articles does not contain any sort of unique ID?

Inside your ng-repeat there is an angular variable: $index which gives you the position of the element in the array (news.articles). You can use it in order to access to the n element in the array.
So, you would have a function which you would call on you view button like this:
$scope.view = function (idx){
//get the n-esim article inside the array like something like
var element = $scope.news[idx] //and do some stuff with element
}
... and in your view you would have something like
<div class="card" style="width: 20rem;" ng-repeat="n in news.articles | filter:searchText | filter:selectedAuthor">
<!--...-->
<a class="btn btn-primary" role="button" ng-click="view($index)">Details</a>
<!--...-->
<a class="btn btn-primary" href="#" role="button"><i class="fa fa-thumbs-up" aria-hidden="true"></i></a>
<a class="btn btn-danger" href="#" role="button"><i class="fa fa-thumbs-down" aria-hidden="true"></i></a>
</div>
</div>

Related

how to stop iterating my like button inside my post

I am working on a post system with likes where the user can toggle the post`s like I have done everything correctly except the last step, the problem inside my v-for loop I fetch likes table from post-like relation(many to many since likes table has user_id and post_id) but it is iterating my button even when I add a condition look here-> duplicated like button, I have tried many things v-if, v-show I think the problem is with my algorithm I hope someone can fix that for me thanks.
<div class="panel panel-white post panel-shadow" v-for="post in posts" >
<div class="post-heading">
<div class="pull-left image">
<img v-bind:src="'img/profile/' + post.user.photo" class="img-circle avatar" alt="user profile image">
</div>
<div class="pull-left meta">
<div class="title h5">
<b>{{post.user.name}} </b>
made a post.
</div>
<h6 class="text-muted time">{{post.created_at | hour}}</h6>
</div>
</div>
<div class="post-description">
<p>{{post.content}}</p>
<div class="stats">
<button class="btn btn-default stat-item" #click.prevent="addLike(post.id)">
<i class="fa fa-thumbs-o-up" aria-hidden="false" style="color: blue" v-for="(like) in post.likes" v-bind:style="like.user_id===id && like.post_id===post.id?'color: blue;':'color: gray;'" > Like {{post.likes.length}}
</i> <!-- here is the duplicate problem-->
</button>
<a class="btn btn-default stat-item" #click.prevent>
<i class="fa fa-reply-all"> {{post.comments.length}}</i> Comments
</a>
</div>
</div>
<comment-input :post="post" :userId="id" :userPhoto="userPhoto"></comment-input>
<ul class="comments-list" v-for="comment in post.comments?post.comments:''">
<comments :comment="comment" :userId="id" :userPhoto="userPhoto"></comments>
</ul>
</div>
<hr>
</div>
</div>
Don't loop through the button element, try to use a method likedBythisUser to check if the current user liked the post in order to bind it to the button style :
methods:{
likedBythisUser(post,id){
return post.likes.find(like=>{
return like.user_id===id && like.post_id===post.id;
}) // return a boolean value
}
}
template :
<button class="btn btn-default stat-item" #click.prevent="addLike(post.id)">
<i class="fa fa-thumbs-o-up" aria-hidden="false" style="color: blue" bind:style="likedBythisUser(post,id)?'color: blue;':'color: gray;'" > Like {{post.likes.length}}
</i> <!-- here is the duplicate problem-->
</button>

Clear Form Input Inside ng-repeat AngularJS

A part of our website includes users replying to reviews posted by other users. All replies(inputs) are bound to the same ng-model. In the HTML code, there's a form that is repeated, over and over again using ng-repeat. The problem is that after a user posts a reply the form doesn't get cleared, so the next user replying to the review, is left with a box that includes the review of the previous user, and therefore has to override it.
Here's our HTML code:
<li ng-repeat="reply in review.replies">
<div class="comment-avatar">
<img src="http://i9.photobucket.com/albums/a88/creaticode/avatar_2_zps7de12f8b.jpg" alt="">
</div>
<div class="comment-box">
<div class="comment-head">
<h6 ng-if="reply.authorType == 'user'" class="comment-name">{{reply.user.name}}</h6>
<h6 ng-if="reply.authorType == 'business'" class="comment-name by-author"> {{business.name}}</h6>
<span style="margin-top: 10px">{{reply.timestamp | date: 'd MMM, yy h:mm a ' }}
<i ng-click="deleteReply(review, reply)" class="delete glyphicon glyphicon-trash"></i>
</span>
</div>
<div class="comment-content">
{{reply.reply}}
</div>
</div>
</li>

Passing data to model inside the ng-click

I am displaying all of the articles from the database and I've created a simple text search for it.
<input ng-model="searchText" placeholder="Search for articles" class="search-text">
And I am filtering the content from the searchText
<section class="articles" ng-repeat="contentItem in content | filter:searchText">
Now what I'm trying is to have buttons with the categories and tags from my database and to be able to filter the content based on the button values.
<span ng-repeat="category in categories">
<button ng-click="searchText = '{{category.local.name}}'" class="btn btn-primary">{{ category.local.name }}</button>
</span>
The code above is not working but for example if I'm taking out the ng-repeat and type all the categories myself it will work:
<span>
<button ng-click="searchText = 'some text'" class="btn btn-primary">Some text</button>
</span>
My question is how can be the good way to pass the content from the search input and buttons to the filter method?
Here is the full code:
<div class="container">
<h1>List of articles</h1>
<section class="search-items">
<input ng-model="searchText" placeholder="Search for articles" class="search-text">
<div class="row">
<div class="col-sm-6">
<h6>Search based on categories:</h6>
<span ng-repeat="category in categories">
<input type="button" ng-click="searchText = '{{ category.local.name }}'" value="{{ category.local.name }}" class="btn btn-primary">
</span>
</div>
<div class="col-sm-6">
<h6>Search based on tags:</h6>
<span ng-repeat="tag in tags">
<input type="button" ng-click="searchText = '{{tag.local.name}}'" value="{{ tag.local.name }}" class="btn btn-primary">
</span>
</div>
</div>
</section>
<section class="articles" ng-repeat="contentItem in content | filter:searchText">
<article class="well">
<h3>{{ contentItem.local.title }}</h3>
<p>{{ contentItem.local.content }}</p>
<span><b>Article author: {{ contentItem.local.author }}</b></span><br/>
<span class="label label-primary">{{ contentItem.local.categories.category }}</span>
<span class="label label-primary">{{ contentItem.local.tags.tag }}</span>
</article>
</section>
</div>
angular.module('myApp', [])
.controller('ThingsController', function(){
var ctrl = this;
ctrl.things = ['thing 1', 'thing 2', 'another thing']
ctrl.searchText = "something"
})
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ThingsController as thingCtrl">
<div ng-repeat="thing in thingCtrl.things">
<button ng-click="thingCtrl.searchText = thing">{{thing}}</button>
</div>
<pre>{{thingCtrl.searchText}}
Above snippet shows it working also using controller as syntax. Typically you don't want to use the $scope as though it's your model you want it to point to your model otherwise you may run into some weird prototypical inheritance problems. As in $scope.myModel = {someProp:4} instead of $scope.someProp = 4 using the controller as syntax also avoids this issue.
What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

Angular JS image display error

I have uploaded image in upload table using grids and MongoDB and I have stored image name in store table.
When I get store details first i have taken image name and check from upload table and displaying the image.
Here I am looping that image name its working but it always showing last image. I have enclosed my html and controller.
$http.get('***').success(function(data,dealers,response) {
var storelen=data.length;
console.log(storelen);
for(var i=0;i<storelen;i++) {
var storeimages=JSON.stringify(data[i].Store_Images);
var storeimages=(storeimages.replace(/\"/g, ""));
console.log(storeimages);
$http.get('***').success(function(data, status,response) {
$scope.image=data;
console.log($scope.image);
});
}
$scope.dealers = data;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ion-view >
<ion-content style="margin-top:50px;" ng-controller="ListingCtrl" data-ng-init="find()">
<div class="list card" data-ng-repeat="dealer in dealers | filter:query | filter:myFilter">
<div class="item item-thumbnail-left item-icon-right" href="#">
<img src="{{image}}" id="myimage">
<h2>{{dealer.Store_Name}}</h2>
<p>{{dealer.S_Address.city}} , {{dealer.S_Address.area}}</p>
<div class="row" style="padding:0px;">
<div class="col-90"><p style="font-size:10px">review</p></div>
<div class="col-10" style="margin-left:30px;">
<i style="right:0px;font-size:18px;color:#ff6f00;"class="icon ion-ios-location subdued"></i>
</div>
</div>
<div class="row" style="padding:0px;">
<div class="col" style="padding: 0px;"><p style="font-size:14px;" listing-rating rating-value="rating" max="5"></div>
</div>
</div>
<div class="item tabs tabs-secondary tabs-icon-left">
<a class="tab-item" ng-href="tel:{{dealer.S_Phone.number}}">
<i class="icon ion-ios-telephone " ></i>
Contact Now
</a>
<a class="tab-item" style="color:green;">
<i class="icon ion-pricetags"></i>
Email
</a>
<a class="tab-item" style="color:#ff6f00;" >
<i class="icon ion-wand" ></i>
Check Now
</a>
</div>
</div>
</ion-content>
</ion-view >
In my table having 3 images, I am getting 3 images in console, but html I am always getting the last image.
I want to display image with in ng-repeat is there any other way doing it ?

Value of object inside json object is not evaluating in nested ng-repeat

My app has a web service that returns the following json array
[{"id":1,"title":"Jeans #1","description":"Jeans Description Of Jeans #1","gender":1,"waists":[{"id":1,"sizeString":"28","enabled":true,"gender":1},{"id":3,"sizeString":"30","enabled":true,"gender":1}],"inseams":[{"id":1,"sizeString":"28","enabled":true,"gender":1},{"id":2,"sizeString":"29","enabled":true,"gender":1}],"style":{"id":1,"styleName":"Style #1","enabled":true,"gender":1},"ctr":0,"colorAndPatterns":[{"id":2,"description":"Green","background":"#00FF00","enabled":true,"gender":1},{"id":1,"description":"Red","background":"#FF0000","enabled":true,"gender":1}],"productOverviews":[{"id":3,"description":"Straight leg","enabled":true,"gender":1},{"id":1,"description":"Slim through thigh","enabled":true,"gender":1}],"enabled":true,"firstJeansImagesBycolor":[{"id":2,"colorAndPatternId":2,"enabled":true},{"id":6,"colorAndPatternId":1,"enabled":true}],"allJeansImagesByColor":[{"id":1,"colorAndPatternId":2,"enabled":true},{"id":2,"colorAndPatternId":2,"enabled":true},{"id":3,"colorAndPatternId":2,"enabled":true},{"id":4,"colorAndPatternId":2,"enabled":true},{"id":5,"colorAndPatternId":1,"enabled":true},{"id":6,"colorAndPatternId":1,"enabled":true},{"id":7,"colorAndPatternId":1,"enabled":true},{"id":8,"colorAndPatternId":1,"enabled":true}]}]
I am using angular's ng-repeat directive to iterate through the json array in the following manner
<div ng-repeat="jean in currentJeans">
<div class="col-xs-4 jeans-listing at-repeat-twirl-in at-repeat-twirl-out" ng-repeat="colors in jean.colorAndPatterns | filter:{id:currentColorId}">
<a href="#/jeans-details/{{jean.id}}" class="thumbnail">
<img ng-src="static/images/jeans/{{jean.id}}/{{colors.id}}/{{jean.firstJeansImagesBycolor[$index].id}}.jpg" alt="Jeans Image"/>
<div class="caption">
<h5 class="text-center">{{jean.title}}</h5>
</div>
<button class="btn btn-default btn-sm" style="position: absolute;top:100px;left:30%;display:none;color:white;background-color:rgba(0,0,0,0.4)"><i class="fa fa-search"></i> Quick View</button>
</a>
</div>
</div>
The problem i 'm facing is this expression evaluates to nothing
{{jean.firstJeansImagesBycolor[$index].id}}
Is this the right way to access arrays inside json objects or not what i 'm doing wrong ??
Here is the link to JSFiddle
It is working perfectly fine. I just printed the path given and it prints:
http://jsfiddle.net/pfgkna8k/3/
<div ng-app="lists">
<div ng-controller="ProductList">
<div ng-repeat="jean in currentJeans">
<div class="col-xs-4 jeans-listing at-repeat-twirl-in at-repeat-twirl-out" ng-repeat="colors in jean.colorAndPatterns | filter:{id:currentColorId}">
<a href="#/jeans-details/{{jean.id}}" class="thumbnail">
<img ng-src="static/images/jeans/{{jean.id}}/{{colors.id}}/{{jean.firstJeansImagesBycolor[$index].id}}.jpg" alt="Jeans Image"/>
static/images/jeans/{{jean.id}}/{{colors.id}}/{{jean.firstJeansImagesBycolor[$index].id}}.jpg
<div class="caption">
<h5 class="text-center">{{jean.title}}</h5>
</div>
<button class="btn btn-default btn-sm" style="position: absolute;top:100px;left:30%;display:none;color:white;background-color:rgba(0,0,0,0.4)"><i class="fa fa-search"></i> Quick View</button>
</a>
</div>
</div>
</div>
</div>

Categories