how to print array object array in html using angualrjs - javascript

I am trying to take data from a movie API (TMDB API) and want to display the details of the movie in my html view page.
I got the response from the API but i cannot figure out the way to handle the response that is in array of an object array.
This is my response
{
"page":1,
"total_results":1,
"total_pages":1,
"results":
[{
"vote_count":779,
"id":20453,
"video":false,
"vote_average":7.7,
"title":"3 Idiots",
"popularity":1.963226,
"poster_path":"\/wbE5SRTZFtQxgj2nIo4HJpQDk0k.jpg",
"original_language":"hi",
"original_title":"3 Idiots",
"genre_ids":[18,35,10749],
"backdrop_path":"\/6LnwpadKFRrqam7IfBAi3lNTz6Y.jpg",
"adult":false,
"overview":"In the tradition of “Ferris Bueller’s Day Off” comes this
refreshing comedy about a rebellious prankster with a crafty mind anda
heart of gold. Rascal. Joker. Dreamer. Genius... You've never met a
college student quite like \"Rancho.\" From the moment he arrives at
India's most prestigious university, Rancho's outlandish schemes turn
the campus upside down—along with the lives of his two newfound best
friends. Together, they make life miserable for \"Virus,\" the
school’s uptight and heartless dean. But when Rancho catches the eye
of the dean's sexy daughter, Virus sets his sights on flunking out the
\"3 idiots\" once and for all.",
"release_date":"2009-12-23"
}]
}
I want to display overview and other details that is in results in my html page using angularjs but i cannot figure out how to do that?
This is my js and html code snippet. Where i try this with another API but now it got private so i have to change the API.
function getItems(){
$http({method:'GET',url:"https://api.themoviedb.org/3/search/movie?api_key=9a1750d469929884b1c959126ec22c83&query=" + $scope.search})
.then(function (response) {
// body...
$scope.movies = response.data.results;
console.log(response.data.results);
});
<div class="movie-details col-sm-8" >
<ul class="details">
<li><img ng-src="{{movies.Poster=='N/A' && 'http://placehold.it/150x220&text=N/A' || movies.poster_path}}" class="movie-poster thumbnail"><a class="movie-title" href="http://www.imdb.com/title/{{movies.imdbID}}" target="_blank">{{movies.original_title}}</a>, {{movies.Year}} <span class="reviews">Reviews | Add your own review</span></li>
<li><span>Released On: </span>{{movies.results}}</li>
<li><span>Runtime: </span>{{movies.Runtime}}</li>
<li><span>Genre: </span>{{movies.Genre}}</li>
<li><span>Director: </span>{{movies.Director}}</li>
<li><span>Writers: </span>{{movies.Writer}}</li>
<li><span>Actors: </span>{{movies.Actors}}</li>
<li>{{movies.overview}}</li>
<li><span>Language: </span>{{movies.Language}}</li>
<li><span>Country: </span>{{movies.Country}}</li>
<li><span>Awards: </span>{{movies.Awards}}</li>
<li><span>IMDB Ratings: </span>{{movies.imdbRating}}</li>
</ul>
<br>
<div>
<a class="links" href="https://www.youtube.com/results?search_query={{movies.original_title}}" target="_blank">Watch Trailers!</a>
|<a class="links" href="https://subscene.com/subtitles/title?q={{movies.Title}}&l=" target="_blank">Get Subtitles!</a>
|<a class="links" href="http://www.amazon.in/s/ref=nb_sb_noss_1?url=search-alias%3Ddvd&field-keywords={{movies.Title}}" target="_blank">Buy Online!</a>
</div>
</div>

You have to use ng-repeat in order to show data in your html, further correct the property names that you bind on html. (for example: results to release_date)
(see this screenshot of console log data)
Sample DEMO :
var myApp = angular.module('myApp', []);
myApp.controller('ExampleController', ExampleController);
function ExampleController($scope, $http) {
function callapi() {
$http({
method: 'GET',
url: 'https://api.themoviedb.org/3/search/movie?api_key=9a1750d469929884b1c959126ec22c83&query=3%20idiot'
}).then(function(response) {
console.log(response.data.results[0]);
$scope.moviesData= response.data.results;
})
}
callapi();
}
<script src="https://code.angularjs.org/1.5.2/angular.js"></script>
<div ng-app="myApp" ng-controller="ExampleController">
<ul ng-repeat="movies in moviesData">
<li><span>Released On: </span>{{movies.release_date}}</li>
<li><span>Runtime: </span>{{movies.Runtime}}</li>
<li><span>Genre: </span>{{movies.Genre}}</li>
<li><span>Director: </span>{{movies.Director}}</li>
<li><span>Writers: </span>{{movies.Writer}}</li>
<li><span>Actors: </span>{{movies.Actors}}</li>
<li>{{movies.overview}}</li>
<li><span>Language: </span>{{movies.original_language}}</li>
<li><span>Country: </span>{{movies.Country}}</li>
<li><span>Awards: </span>{{movies.Awards}}</li>
<li><span>IMDB Ratings: </span>{{movies.imdbRating}}</li>
<hr>
</ul>
</div>

It looks like you are not using the results exactly as you should be. For instance you have movies.results but you already set $scope.movies to your return results properties.
Make sure that you are using the properties within the results property that you set movies to.
For example you could access the overview by calling {{movies.overview}} in your HTML

Related

how to get videoCategoryId from videoID youtubube api

Website link if you want to know how it works - https://nerdtube.000webhostapp.com/home.html
i am building a site where only education category videos would be fetched and iframed. Like if someone inputs "cat" in my searchbar, i should only get cat videos/playlist which have category "education". I have the videoID, but i dont seem to find the category ID in the json returned.
function search(id,tit) {
//console.log(id);
var key = 'MY API KEY';
//playlistId = 'PLUl4u3cNGP6317WaSNfmCvGym2ucw3oGp';
var playlistId=id;
var URL = 'https://www.googleapis.com/youtube/v3/playlistItems';
//playlistId=document.getElementById('searchTerm').value;
//console.log(playlistId);
$('#plname').html(
`<h1>Playlist : ${tit}</h1>`
)
var options = {
part: 'snippet',
key: key,
maxResults: 60,
playlistId: playlistId,
}
//console.log(playlistId);
loadVids();
function loadVids() {
$.getJSON(URL, options, function (data) {
var id = data.items[0].snippet.resourceId.videoId;
console.log(data);
resultsLoop(data);
mainVid(id);
});
}
function mainVid(id) {
document.getElementById('plname').style.display="block";
$('#video').html(`
<iframe src="https://www.youtube.com/embed/${id}" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
`);
}
function resultsLoop(data) {
document.getElementById('dec').style.display="block";
$.each(data.items, function (i, item) {
var thumb = item.snippet.thumbnails.medium.url;
var title = item.snippet.title;
var desc = item.snippet.description.substring(0, 100);
var vid = item.snippet.resourceId.videoId;
$('main').append(`
<a>
<article class="item" data-key="${vid}">
<img src="${thumb}" alt="" class="thumb">
<div class="details">
<h4>${title}</h4>
<p>${desc}</p>
</div>
</article>
</a>
`);
});
}
// CLICK EVENT
$('main').on('click', 'article', function () {
var id = $(this).attr('data-key');
mainVid(id);
});
}
so what i am doing is (code not shown here) i first get objects that are playlist type from searchbar, show the playlists and when someone clicks on a playlist, this search(id, tit) function starts which gradually fetches all the videos in that playlist. Now i want to filter only the education category videos but json doesnt have that part i guess.
Edit:
I probably misunderstood your question and your usecase. Sorry for the confusion. But I think the answer and especially the comments are useful so I decided not to delete the answer.
Thanks #stvar for your comments
My recommendation
For me your usecase sounds like it would be better to use the API endpoint "serach/list" or "videos/list" instead of the API endpoint "playlistItems".
By using the endpoint "serach/list" or "videos/list" you can already restrict the results to the video category by specifiying the "videoCategoryId" in the initial request.
For example:
https://www.googleapis.com/youtube/v3/search?videoCategoryId=[YOUR_VIDEO_CATEGORY_ID]&...
https://www.googleapis.com/youtube/v3/videos?videoCategoryId=[YOUR_VIDEO_CATEGORY_ID]&...
I would recommend to specify as much parameters as possible in order to have the best possible results for your site/application. But note that not all combinations are allowed.
Use the "Try this API" in the API documentation in order to narrow your request:
https://developers.google.com/youtube/v3/docs/search/list
https://developers.google.com/youtube/v3/docs/videos/list
Keep in mind that the endpoint "search/list" has a significantly increased cost-factor for the API quotas. It provides more flexibility so you can include or exlude live streams and specify much more options in comparison to "videos/list".
Alternative method (not verified by testing it myself)
This is not working as explained in the comments because "id" and "videoCategoryId" are exclusive parameters.
If this is not an option for you then you can make an additional API call for each video in the result of your "playlistItems" API call.
Specify the "Video ID"" and "Video Category ID". If you get no result skip the video and do not show it on your site, e.g.:
https://www.googleapis.com/youtube/v3/videos?id=[YOUR_VIDEO_ID]&videoCategoryId=[YOUR_VIDEO_CATEGORY_ID]&...

Angular.js - Slicing a json request according to user input

I am a beginner at Angular.js and am currently going through the tutorial. I decided to try making the number of phones displayed changeable by the user. In my controller:
function PhoneListController($http) {
var self = this;
self.orderProp = 'age';
$http.get('phones/phones.json').then(function(response) {
self.phones = response.data.slice(0, self.displayNum);
});
}
PhoneListController.$inject = ['$http']; //services to inject for each parameter in PhoneListController
I slice the response data that I get from the server according to the displayNum input by the user. I'm sure that displayNum is updated in the model, however it doesn't slice the json as I expected it to. Is the http request only made once at the start?
The relevant section of my template:
<p>
Number of phones displayed:
<input ng-model="$ctrl.displayNum" />
</p>
...
<ul class="phones">
<li ng-repeat="phone in $ctrl.phones | filter:$ctrl.query | orderBy:$ctrl.orderProp">
<span>{{phone.name}}</span>
<p>{{phone.snippet}}</p>
</li>
</ul>
<p>display num: {{$ctrl.displayNum}}</p>
The display num: {{$ctrl.displayNum}} at bottom updates according to the number input in <input ng-model="$ctrl.displayNum" />, but the list does not change size. If I hardcode a value in for self.displayNum in the controller the list is sliced correctly when I refresh the page, but changing the value in the input does nothing to the list.
As mentioned by #Alexander-Bolzhatov, I simply put the http request in a change function, called by ng-change in the template.
$http.get('phones/phones.json').then(function(response) {
self.phones = response.data;
});
self.change = function(){
$http.get('phones/phones.json').then(function(response) {
self.phones = response.data.slice(0, self.displayNum);
});
};
Template code:
Number of phones displayed:
<input ng-model="$ctrl.displayNum" ng-change="$ctrl.change()"/>

How to handle JSON data using AngularJS?

Currently I have a json file that populates information to my chart. An example of this chart can be found here: http://marmelab.com/ArchitectureTree/. I also have a panel to the right which is meant to display the information of one of the charts node's when clicked. However I don't know how to do this.
Say if I had in my json array:
{
"name": "Blogs",
"url": "blogs.my-media-website.com/*",
"dependsOn": ["Wordpress MU"],
"technos": ["PHP", "Wordpress"],
"host": { "Amazon": ["?"] }
},
I would click on 'Blogs' in the chart and the 'url', 'dependsOn' etc would then be displayed in the panel. I'm sure this function uses AngularJS to do this. Can someone point me in the right direction on how to do this?
On click of Blogs call below function :
In your controller, try adding this function.
$scope.onClickOfBlogs = function(){
$http.get('Your_JSON_file_Path_here').success(function(response){
$scope.jsonObject= response;
}).error(function() {
console.log('error occured while getting JSON file');
});
};
in your Panel HTML : -
<div id ="info">
<span>URL : {{jsonObject.url}} </span>
<span>Name : {{jsonObject.name}} </span>
<ul>
Depends on :
<li ng-repeat = "depends in jsonObject.dependsOn"> <!-- to iterate on array you need ng-repeat -->
{{depends}}
</li>
</ul>
</div>
you will get the data from json file into your html panel.Hope this helps.
**
** : http://plnkr.co/edit/dbJ0bhHhvASffJU9liY6?p=preview

Angularjs: HTML DOM is not updated

I've an inherited project writed in django 1.4 and I've no time to update it to another version of django.
I'm introducing angularjs in that project being newbie with it.
So, I've a HTML filled with data from the database (very simplified code):
<div ng-app="myApp" ng-controller="commentController">
<input placeholder="say something!" type="text">
<button class="btn" ng-click="sendComment()" >
<li ng-repeat="comment in comments" id="aportacion{{comment.pk}}">
{{comment.username}} - {{comment.text}}
</li>
</div>
And angularjs app (simplified) to fill the table with comments:
var app = angular.module("myApp", []);
app.controller("commentController",function ($scope) {
$scope.comments = [];
// this is generated dinamically with django from db data on page generation;
$scope.comments[$scope.comments.length] = {"username":"inigod", "text":"this is sparta"};
$scope.comments[$scope.comments.length] = {"username":"another guy", "text":"this is NOT sparta"};
.......
};
});
This works great, it builds all the comments ok, nice.
Now I've a textbox to add new comment and want to send via ajax the new comment to db and with the response json add a new comment in the top of the comments in html.
I've tried modificating the angularjs code to this:
app.controller("commentController",function ($scope) {
$scope.comments = [];
// this is generated dinamically with django from db data on page generation;
$scope.comments[$scope.comments] = {"username":"inigod", "text":"this is sparta"};
$scope.comments[$scope.comments] = {"username":"another guy", "text":"this is NOT sparta"};
$scope.sendComment = function(){
Dajaxice.kolokvoweb.post_comment($scope.comment_callback, {'thread':'{{thread.pk}}',
'type': 0,
'text': $('#comment').val(),
});
}
$scope.comment_callback = function (data){
if (data.result){
data["image"]= "/img/comment-placeholder.png";
//data["$$hashKey"] = "003";
alert("adding element" +$scope.aportaciones.length);
$scope.comments.push(data);
alert("added element" +$scope.aportaciones.length);
}
}
So I run this and I get two alert, one saying "adding element n" and the next "added element n+1" so it appears to reach to $scope.comment_callback an push the data to the array but the DOM is not updated and I cannot see the inserted comment in the page.
I must be something wrong but cannot find what...
I've see the response from ajax and is the same kind of JSON but withouth the $$haskey key.
PD: received data from the ajax service is:
{"username":"inigo","texto":"ggggggggggggggggggggggg","date":"now","result":true,"pk":74,"foto":"/img/agora-placeholder.png"}
The one getted when loading page for that comment (and which is well shown in the page) is:
{"pk":"74","texto":"ggggggggggggggggggggggg","username":"inigo","date":"10/11/14","foto":"/img/agora-placeholder.png"}
You have to wrap the content of comment_callback in a $scope.$apply method to notify about $scope changes within async callbacks:
$scope.comment_callback = function (data){
if (data.result){
$scope.$apply(function() {
data["image"]= "/img/comment-placeholder.png";
$scope.comments.push(data);
});
}
}

I have two divs with the same ng-controller in AngularJS, how can I make them share information?

I have two different div tags in my html code referencing the same controller in AngularJS. What I suspect is that since these divs aren't nested they each have their own instance of the controller, thus the data is different in both.
<div ng-controller="AlertCtrl">
<ul>
<li ng-repeat="alert in alerts">
<div class="span4">{{alert.msg}}</div>
</li>
</ul>
</div>
<div ng-controller="AlertCtrl">
<form ng-submit="addAlert()">
<button type="submit" class="btn">Add Alert</button>
</form>
</div>
I know this could easily be fixed by including the button in the first div but I feel this is a really clean and simple example to convey what I am trying to achieve. If we were to push the button and add another object to our alerts array the change will not be reflected in the first div.
function AlertCtrl($scope) {
$scope.alerts = [{
type: 'error',
msg: 'Oh snap! Change a few things up and try submitting again.'
}, {
type: 'success',
msg: 'Well done! You successfully read this important alert message.'
}];
$scope.addAlert = function() {
$scope.alerts.push({
type: 'sucess',
msg: "Another alert!"
});
};
}
This is a very common question. Seems that the best way is to create a service/value and share between then.
mod.service('yourService', function() {
this.sharedInfo= 'default value';
});
function AlertCtrl($scope, yourService) {
$scope.changeSomething = function() {
yourService.sharedInfo = 'another value from one of the controllers';
}
$scope.getValue = function() {
return yourService.sharedInfo;
}
}
<div ng-controller="AlertCtrl">{{getValue()}}</div>
<div ng-controller="AlertCtrl">{{getValue()}}</div>
If I understand the question correctly, you want to sync two html areas with the same controller, keeping data synced.
since these divs aren't nested they each have their own instance of the controller, thus the data is different in both
This isn't true, if you declare the controllers with the same alias (I'm using more recente angular version):
<div ng-controller="AlertCtrl as instance">
{{instance.someVar}}
</div>
<div ng-controller="AlertCtrl as instance">
{{instance.someVar}} (this will be the same as above)
</div>
However, if you WANT them to be different and comunicate each other, you will have to declare different aliases:
<div ng-controller="AlertCtrl as instance1">
{{instance1.someVar}}
</div>
<div ng-controller="AlertCtrl as instance2">
{{instance2.someVar}} (this will not necessarily be the same as above)
</div>
Then you can use services or broadcasts to comunicate between them (the second should be avoided, tough).

Categories