how to show api data with angularJs in html - angularjs

Hello i have the following code and i want to show the objects that the api returns in to my html but i am drawing a blank on this, also i want to make a filter to sort by id.
angular.module('MainApp').controller('PhoneController', function ($scope, $http) {
$scope.home = "This is the homepage";
$scope.getRequest = function () {
console.log("I've been pressed!");
$http.get("http://api.myjson.com/bins/12qiaa")
.then(function successCallback(response) {
$scope.response = response;
console.log(response.data.galerija);
var row0 = response.data.galerija[0];
var row1 = response.data.galerija[1];
var row2 = response.data.galerija[2];
var row3 = response.data.galerija[3];
var row4 = response.data.galerija[4];
var row5 = response.data.galerija[5];
}, function errorCallback(response) {
console.log("Unable to perform get request");
});
};

To populate your html you will have to bind your modal to the view. Angular uses handlebar syntax.
First thing is to declare your model, let's say $scope.galerijas, then after your $http GET request you will populate response to your $scope.galerijas model.
Finally we will use ng-repeat to loop over $scope.galerijas and bind it to the view. A filter | is used to order the displayed results by id.
Sample Html
<div ng-app="MainApp" ng-controller="PhoneController">
<h2>{{ home }}</h2>
<ul>
<li ng-repeat="x in galerijas | orderBy:'id'">
<figure class="figure">
<img src="{{ x.slika }}" class="figure-img img-fluid rounded" alt="{{ x.naziv }}">
<figcaption class="figure-caption text-right">{{ x.naziv }}</figcaption>
</figure>
</li>
</ul>
<button type="button" ng-click="getRequest()">Get Galerija</button>
</div>
Sample Script
var app = angular.module("MainApp", []);
app.controller("PhoneController", function($scope, $http) {
$scope.home = "This is the homepage";
$scope.galerijas = []; // This will hold all our galerija after ajax request;
$scope.getRequest = function() {
console.log("I've been pressed!");
$http.get("https://api.myjson.com/bins/12qiaa")
.then(function successCallback(response) {
console.log(response.data.galerija);
$scope.galerijas = response.data.galerija; // populate from api;
}, function errorCallback(response) {
console.log("Unable to perform get request");
});
console.log($scope.galerijas);
}
});
And here is an example fiddle: https://jsfiddle.net/tbxmfarz/3/

Related

Output image from RESTful Service Angular

I am new to Angular so to get to grips with it I have been working with a Dummy RESTful service. Right now I have managed to pull the image URL and then push it into an array.
I would like to output this array as an image when the "ng-click" directive is fired.
Any guidance or help would be much appreciated.
<p ng-click="outputImageData()">click me</p>
<ul>
<li ng-repeat="photo in photos">
{{ image }}
</li>
</ul>
myApp.factory('getImages', function($http) {
var imageService = {
async: function(id) {
var promise = $http.get('https://jsonplaceholder.typicode.com/photos/1').then(function(response) {
return response.data;
})
return promise;
}
};
return imageService;
});
myApp.controller("outputImages", function($scope, getImages) {
var photos = [];
$scope.outputImageData = function() {
getImages.async().then(function(data) {
var photoId = data.url;
photos.push(photoId);
console.log(photos);
})
}
});
Thanks
I've been using angularjs but generally as a developer, I'm just started so bear with me, please.
I think something like this would work:
<p ng-click="updateImageData()">click me</p>
<ul>
<li ng-repeat="photo in photos">
<img src="{{photo.url}}">
</li>
</ul>
myApp.factory('getImages', function($http) {
var imageService = {
async: function() {
var promise = $http.get('https://jsonplaceholder.typicode.com/photos/');
return promise;
}
};
return imageService;
});
myApp.controller("outputImages", function($scope, getImages) {
$scope.photos = [];
$scope.updateImageData = function() {
getImages.async(photoId).then(function(data) {
$scope.photos = data;
console.log(photos);
})
}
});

AngularJs requires page refresh after API call

I am writing an angularjs app. The requirement is to display the user's data once the user logs in. So when an user successfully logs in, he/she is routed to the next view. My application is working fine upto this point. Now as the next view loads I need to display the existing records of the user. However at this point I see a blank page, I can clearly see in the console that the data is being returned but it is not binding. I have used $scope.$watch, $scope.$apply, even tried to call scope on the UI element but they all result in digest already in progress. What should I do? The page loads if I do a refresh
(function () {
"use strict";
angular.module("app-newslist")
.controller("newsController", newsController);
function newsController($http,$q,newsService,$scope,$timeout)
{
var vm = this;
$scope.$watch(vm);
vm.news = [];
vm.GetTopNews = function () {
console.log("Inside GetTopNews");
newsService.GetNewsList().
then(function (response)
{
angular.copy(response.data, vm.news);
}, function () {
alert("COULD NOT RETRIEVE NEWS LIST");
});
};
var el = angular.element($('#HidNews'));
//el.$scope().$apply();
//el.scope().$apply();
var scpe = el.scope();
scpe.$apply(vm.GetTopNews());
//scpe.$apply();
}
})();
Thanks for reading
you don't show how you're binding this in your template.. I tried to recreate to give you a good idea.
I think the problem is the way you're handling your promise from your newsService. Try looking at $q Promises. vm.news is being updated by a function outside of angular. use $scope.$apply to force refresh.
the original fiddle is here and a working example here
(function() {
"use strict";
var app = angular.module("app-newslist", [])
.controller("newsController", newsController)
.service("newsService", newsService);
newsController.$inject = ['$http', 'newsService', '$scope']
newsService.$inject = ['$timeout']
angular.bootstrap(document, [app.name]);
function newsController($http, newsService, $scope) {
var vm = this;
vm.news = $scope.news = [];
vm.service = newsService;
console.warn(newsService)
vm.message = "Angular is Working!";
vm.GetTopNews = function() {
console.log("Inside GetTopNews");
newsService.GetNewsList().
then(function(response) {
$scope.$apply(function() {
$scope.news.length > 0 ? $scope.news.length = 0 : null;
response.data.forEach(function(n) {
$scope.news.push(n)
});
console.log("VM", vm);
})
}, function() {
alert("COULD NOT RETRIEVE NEWS LIST");
});
};
}
function newsService($timeout) {
return {
GetNewsList: function() {
return new Promise(function(res, rej) {
$timeout(function() {
console.log("Waited 2 seconds: Returning");
res({
data: ["This should do the trick!"]
});
}, 2000);
})
}
}
}
})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.9/angular.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.min.js"></script>
<body>
<div class="main">
<div class="body" ng-controller="newsController as vm">
Testing: {{ vm.message }}
<br>{{ vm.news }}
<br>{{ vm }}
<br>
<button class="getTopNewsBtn" ng-click="vm.GetTopNews()">Get News</button>
<br>
<ul class="getTopNews">
<li class="news-item" ng-repeat="news in vm.news track by $index">
{{ news | json }}
</li>
</ul>
</div>
</div>
</body>

Initialise AngularJS service - factory on the document load

Sorry for a very stupid question but I just started working with AngularJS and OnsenUI.
I have got a service to get a data from SQLite:
module.factory('$update', function () {
var update = {};
db.transaction(function (tx) {
tx.executeSql('SELECT * FROM event_updates', [], function (tx, results) {
var rows = results.rows;
update.items = [];
if (!rows.length) {} else {
for (var index = 0; index < rows.length; index++) {
update.items.push({
"title": rows.item(index).title,
"date": rows.item(index).date,
"desc": rows.item(index).desc
});
}
}
}, function (error) {
console.log(error);
});
});
return update;
});
And a controller which is using the data:
module.controller('UpdatesController', function ($scope, $update) {
$scope.items = $update.items;
});
As soon as my page is loaded the content is not displayed and I need to click twice to call a page with the code below to see the content:
<ons-list ng-controller="UpdatesController">
<ons-list-item modifier="chevron" class="list-item-container" ng-repeat="item in items" ng-click="showUpdate($index)">
<div class="list-item-left">
</div>
<div class="list-item-right">
<div class="list-item-content">
<div class="name">{{item.title}}</div> <span class="desc">{{item.desc}}</span>
</div>
</div>
</ons-list-item>
</ons-list>
Can anybody help how can I initialise the controller as soon as page is loaded with all content. Sorry if it is a stupid question but I am really struggling. Appreciate your help a lot.
You could store the result of the request in the factory and retrieve those instead.
module.factory('$update', function () {
var update = {};
var requestValues = function(){ // store the results of the request in 'update'
// Your db.transaction function here
}
var getUpdates = function(){ // retrieve the values from 'update'
return update;
}
return{
requestValues : requestValues,
getUpdates : getUpdates
}
});
And then in you controller:
module.controller('UpdatesController', function ($scope, $update) {
$update.requestValues();
$scope.items = $update.getUpdates();
});
You could then get the values from anywhere in you solution (by using $update.getUpdates) without having to make an extra http request.

Meteor application crashing while calling last message

In one of controller I'm trying to list all online users and their last message. But the browser is unresponsive while running the below code.
In app.js
angular.module('jaarvis').controller('OnlineUsersCtrl', ['$scope', '$meteor', function ($scope, $meteor) {
$scope.$meteorSubscribe('users');
$scope.$meteorSubscribe('chats');
var query = {};
query['status.online'] = true;
var online = $meteor.collection(function(){
return Meteor.users.find(query, {fields: {'_id':1, 'profile.name':1, 'status.online':1}});
});
$scope.onlineusers = online;
$scope.getLastMessage = function(userId) {
var query = {};
query['uid'] = userId;
var lastMessage = $meteor.collection(function(){
return Chats.find({'uid':userId}, {fields: {'content':1}}, {sort: {'_id': -1}, limit: 1});
});
return lastMessage;
};
}]);
In HTML
<div class="list">
<a class="item item-avatar" href="/onetoonechat/{{onlineuser._id}}" ng-repeat="onlineuser in onlineusers">
<img src="venkman.jpg">
<h2>{{onlineuser.profile.name}}</h2>
<p>{{ getLastMessage(onlineuser._id) }}</p>
</a>
</div>
Correct if there is any mistake in my code or provide alternative solution.

if number of results returned > X then hide element angularjs

I would like to detect the amount of results returned in an ng-repeat loop and then if it is more than a certain number, execute code eg. hide an HTML tag. So if p in pics is more than X then hide something. Not sure how to go about it:
Here is a snippet of my code:
HTML
<li ng-repeat="p in pics">
<img ng-src="{{p.images.thumbnail.url}}" />
<p>{{p.comments.data|getFirstCommentFrom:'alx_lloyd'}}</p>
</li>
JS
(function(){
//Place your own Instagram client_id below. Go to https://instagram.com/developer/clients/manage/ and register your app to get a client ID
var client_id = ''; //redacted
//To get your user ID go to http://jelled.com/instagram/lookup-user-id and enter your Instagram user name to get your user ID
var user_id = ''; //redacted
var app = angular.module('instafeed', ['ngAnimate']);
app.filter('getFirstCommentFrom',function() {
return function(arr, user) {
for(var i=0;i<arr.length;i++) {
if(arr[i].from.username==user)
return arr[i].text;
}
return '';
}
})
app.factory("InstagramAPI", ['$http', function($http) {
return {
fetchPhotos: function(callback){
var endpoint = "https://api.instagram.com/v1/users/self/media/liked/";
endpoint += "?access_token=foobar";
endpoint += "&callback=JSON_CALLBACK";
/* var endpoint = "https://api.instagram.com/v1/users/" + user_id + "/media/recent/?";
endpoint += "?count=99";
endpoint += "&client_id=" + client_id;
endpoint += "&callback=JSON_CALLBACK";
*/
$http.jsonp(endpoint).success(function(response){
callback(response.data);
});
}
}
}]);
app.controller('ShowImages', function($scope, InstagramAPI){
$scope.layout = 'grid';
$scope.data = {};
$scope.pics = [];
InstagramAPI.fetchPhotos(function(data){
$scope.pics = data;
console.log(data)
});
});
})();
You can use ng-hide since your pics are just in an array and check the length of the array, e.g:
<h2 ng-hide="pics.length > 5">HIDE ME</h2>
(function() {
//Place your own Instagram client_id below. Go to https://instagram.com/developer/clients/manage/ and register your app to get a client ID
var client_id = '83aaab0bddea42adb694b689ad169fb1';
//To get your user ID go to http://jelled.com/instagram/lookup-user-id and enter your Instagram user name to get your user ID
var user_id = '179735937';
var app = angular.module('instafeed', ['ngAnimate']);
app.filter('getFirstCommentFrom', function() {
return function(arr, user) {
for (var i = 0; i < arr.length; i++) {
if (arr[i].from.username == user)
return arr[i].text;
}
return '';
}
})
app.factory("InstagramAPI", ['$http',
function($http) {
return {
fetchPhotos: function(callback) {
var endpoint = "https://api.instagram.com/v1/users/self/media/liked/";
endpoint += "?access_token=179735937.83aaab0.e44fe9abccb5415290bfc0765edd45ad";
endpoint += "&callback=JSON_CALLBACK";
$http.jsonp(endpoint).success(function(response) {
callback(response.data);
});
}
}
}
]);
app.controller('ShowImages', function($scope, InstagramAPI) {
$scope.layout = 'grid';
$scope.data = {};
$scope.pics = [];
InstagramAPI.fetchPhotos(function(data) {
$scope.pics = data;
console.log(data)
});
});
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular-animate.js"></script>
<div ng-app='instafeed' ng-controller='ShowImages'>
<li ng-repeat="p in pics">
<a href="{{p.link}}" target="_blank">
<img ng-src="{{p.images.thumbnail.url}}" />
</a>
<p>{{p.comments.data|getFirstCommentFrom:'alx_lloyd'}}</p>
</li>
<h2 ng-hide="pics.length > 5">HIDE ME</h2>
</div>
If you want mean is something like "show only the first four results" then you can do this by using $index from the ng-repeat.
For instance the following will show items with 0 <= $index <= 3.
<li ng-repeat="p in pics" ng-if="$index < 4">
You can reference $index anywhere inside the repeat - not just on the repeat itself:
<li ng-repeat="p in pics">
<img ng-src="{{p.images.thumbnail.url}}" />
<p ng-if="$index<4">{{p.comments.data|getFirstCommentFrom:'alx_lloyd'}}</p>
</li>
Alternatively if you want to hide the whole lot then you should be able to take the length from the array:
<div id="container" ng-if="pics.length <= 4">
<li ng-repeat="p in pics">
...
</li>
</div>
For any of these you can choose between ng-if and ng-hide. I would tend to prefer ng-if, as it causes the render to be ignored completely. ng-hide will render all the markup, and then just set to display:none;, which is more likely to be useful where the condition can change due to the user's input to the page (for example).
As #DTing points out, you can also use a filter on the repeat itself if you want to apply the filter at that level:
<li ng-repeat="p in pics | limitTo: 4">

Resources