Access images from local JSON file on the web page in angularjs - angularjs

Where am i going wrong?
I want to access images from datahl.json file on the web page but unable to access them.Please check the codes and help me.
If possible please refer the solution to plunker editor.
index.html
<div class="col-sm-4" ng-repeat = "hbl in hbls">
<div class="thumbnail" ng-repeat = "h in hbl.data_list"
style="width:100%;">
<img ng-src="{{h.img}}" alt="" style="height:50vh;">
<div class="caption">
<p><strong>{{h.name}}</strong></p>
</div>
</div>
</div>
app.js This is my js codes
var app = angular.module('hostellApp', []);
app.controller('hostellController', function($scope, hblsFactory){
$scope.hbls;
hblsFactory.getHbls().then(function(response){
$scope.hbls = response.data;
});
$scope.sayHello = function(){
console.log("Hello");
}
});
app.factory('hblsFactory', function($http){
function getHbls(){
return $http.get('datahl.json');
}
return {
getHbls: getHbls
}
});
datahl.json This is my local JSON file
`
{
"view_type": 5,
"title": "Hostels By Locality",
"position": 5,
"data_list":
[
{
"img": "https://s3.us-east-2.amazonaws.com/images-city-
teens/IMG_20180526_1139570.8091572935412125.jpg",
"name": "Mahavir Nagar"
},
{
"img": "https://graph.facebook.com/1666751513414902/picture?
type=large",
"name": null
},
{
"img": "https://s3.us-east-2.amazonaws.com/images-city-
teens/cropped1148015742983667713.jpg",
"name": "New Rajiv Gandhi"
},
{
"img": "https://s3.us-east-2.amazonaws.com/images-city-
teens/cropped998427941.jpg",
"name": "Jawahar Nagar"
}
]
}`

The data you get from your JSON file is not an array but an object. This means that you only need one ng-repeat.
Change your first ng-repeat to ng-repeat="h in hbls.data_list"(added an 's' to hbl) and delete your second ng-repeat.
Working plunker: https://plnkr.co/edit/OOd1M1dNFjSB7uaqZZB6?p=preview

Related

Only show content associated with user

I have a service that does a request,
.factory('movieService', ['$http', function($http) {
return {
loadMovies: function() {
return $http.get('/movies_users.json');
}
};
}])
This is the JSON output and is the result of 2 tables being joined. A user table and a movie table. As you can see the users are associated with 1 or more movies.
[
{"id":1,
"email":"peter#peter.nl",
"movies":[
{
"id":4,
"title":"Creed",
movie_id":"312221"
},
{
"id":5,
"title":"Star Wars: Episode VII - The Force Awakens",
"movie_id":"140607"
}
]
},
{"id":2,
"email":"jan#jan.com",
"movies":[
{
"id":4,
"title":"Creed",
movie_id":"312221"
}
]
}
]
I then have this function in my controller,
movieService.loadMovies().then(function(response) {
$scope.movies = response.data;
});
This stores the data from the service into the movie scope.
If I do,
"ng-repeat" => "movie in movies"
The ng-repeat shows all the movies added by all the users. How would I only show the movies associated with the current user in a view?
This seems to be what you want - let me know if it helps.
Note that you have an extra " on movie_id" that is certainly not helping
angular.module('myApp', [])
.controller('ctrl', function($scope) {
$scope.users = [
{"id":1,
"email":"peter#peter.nl",
"movies":[
{
"id":4,
"title":"Creed",
movie_id:"312221"
},
{
"id":5,
"title":"Star Wars: Episode VII - The Force Awakens",
"movie_id":"140607"
}
]
},
{"id":2,
"email":"jan#jan.com",
"movies":[
{
"id":4,
"title":"Creed",
movie_id:"312221"
}
]
}
];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="ctrl">
<div ng-repeat="user in users">
{{user.email}}
<div ng-repeat="movie in user.movies">
{{movie.title}}
</div>
</div>
<h2>Movies for user 2</h2>
<div ng-repeat="movie in users[1].movies">
{{movie.title}}
</div>
</div>
Found in a quick google search:
How do I filter an array with AngularJS and use a property of the filtered object as the ng-model attribute?
<div ng-repeat="movie in movies | filter {email:'user#email.com'}">
Edit: it looks like you actually have a list of users, so you could do a filter on an ngrepeat on users, then you'd have a nested ngrepeat on movies (unfiltered because they're attached to a user). But depending on how your app actually needs to work you could just filter the data when it comes back and throw out the users you don't need. Which introduces the question, do you have access to the server side code? If so you could filter there and not return data that is associated with a different user in the first place

$sce:itype Attempted to trust a non-string value in a content requiring a string: Context: resourceUrl

I want to play songs stored in my sails server. Path is http://localhost:4000/images/123.mp3.
In front end, i'm using ng-repeat to list that songs from server.
<div ng-repeat="tones in ringTones track by $index">
<div>
<i ng-show="playpause" class="fa fa-play-circle" ng-click="playpause=!playpause" onclick="plays(event);"><audio id="audio_{{$index}}" ng-src="tones.tonePath"></audio></i>
<i ng-show="!playpause" class="fa fa-pause" ng-click="playpause=!playpause" onclick="stop(event);"></i></div>
</div>
This audio source cause external resource problem
<audio ng-src="tones.tonePath"></audio>
in angular controller, i'm using $sce
$http.get("http://localhost:4000/songs/find").success(function(data){
$rootScope.ringTones=data;
$rootScope.ringTones.push($sce.trustAsResourceUrl(data[0]));
}).error(function(data){
console.log('ERROR');
});
Error is :
Error: [$sce:itype] Attempted to trust a non-string value in a
content requiring a string: Context: resourceUrl
Without using $sce that cause
Error: [$interpolate:interr] Can't interpolate: tones.tonePath
Error: [$sce:insecurl] Blocked loading resource from url not allowed by $sceDelegate policy. URL
This is my JSON from server
[{
"toneName": "2",
"aboutTone": "2",
"duration": 2,
"tonePath": "http://localhost:4000/images/234.mp3",
"createdAt": "2015-08-03T15:40:58.227Z",
"updatedAt": "2015-08-03T15:40:58.227Z",
"id": "55bf8b8a77efb94b32b158c0"
},
{
"toneName": "3",
"aboutTone": "3",
"duration": 3,
"tonePath": "http://localhost:4000/images/123.mp3",
"createdAt": "2015-08-03T15:45:16.120Z",
"updatedAt": "2015-08-03T15:45:16.120Z",
"id": "55bf8c8c77efb94b32b158c1"
}
]
Then how to play external mp3 in my ng-repeat. Help me.
I found solution :
External resource not being loaded by AngularJs
app.filter('trusted', ['$sce', function ($sce) {
return function(url) {
return $sce.trustAsResourceUrl(url);
};
}]);
Then specify the filter in ng-src:
<audio
ng-src="{{tones.tonePath | trusted}}" />
</audio>
Thanks for response.
//first Take data from api
$scope.Data= JSLINQ(data.Data).Select(function (Item) { return Item; })
//Map data as trustable to scope
$scope.Data.items.map(function (i) {
i.Header1 = $sce.trustAsHtml(i.Header1);
});
//UI bind modal data
<p ng-bind-html="x1.Header1 " ng-show="x1.Header1 != null"></p>

ng-options default value from external json file

I have a select
data-ng-model="layout" ng-options="layout.url as layout.name for layout in layouts"
populated from an external json file:
{
"metaDescription": "My website description",
"metaKeywords": "keyword1, keyword2",
"siteTitle": "My Company",
"pageTitle": "Welcome ",
"layout": [
{ "name": "Cerulean", "url": "cerulean" },
{ "name": "Cosmo", "url": "cosmo" },
{ "name": "Cyborg", "url": "cyborg" }
],
"test": "Lorem ipsum dolor"
}
And a controller
function httpController($scope, $http) {
$http.get('content.json').success (function(data){
$scope.layouts = data.layout;
$scope.layout = $scope.layouts[2];
});
};
The $scope.layout = $scope.layouts[2]; should set as the default value but it does not work.
It seems to be working if the JSON array is in the controller but I need to use it from an external JSON and in this case it does not work!
Any help would be appreciated.
You just need to add .url to your $scope.layout = $scope.layouts[2];
In your $http.get() Do the following.
$http.get('URLToGET')
.success(function(data){
$scope.layouts = data.layout;
$scope.layout = $scope.layouts[2].url; //<--- .url
});
Your HTML will look like this:
<select data-ng-model="layout" ng-options="layout.url as layout.name for layout in layouts">
<option value="">Select Url</option>
</select>
Here is a new updated working example
var myApp = angular.module('myApp',[]);
myApp.controller('MyCtrl', function($scope) {
$scope.data = {
"metaDescription": "My website description",
"metaKeywords": "keyword1, keyword2",
"siteTitle": "My Company",
"pageTitle": "Welcome ",
"layout": [
{ "name": "Cerulean", "url": "cerulean" },
{ "name": "Cosmo", "url": "cosmo" },
{ "name": "Cyborg", "url": "cyborg" }
],
"test": "Lorem ipsum dolor"
};
$scope.layouts = $scope.data.layout;
$scope.layout = $scope.layouts[2].url;
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp">
<div ng-controller="MyCtrl">
<select ng-model="layout" ng-options="layout.url as layout.name for layout in layouts">
<option value="">Select Url</option>
</select>
<label ng-bind="layout"></label>
</div>
</div>
For Some clarification
When you use ng-options, the values of option tags written out by
ng-options will always be the index of the array item the option tag
relates to. This is because Angular actually allows you to select
entire objects with select controls, and not just primitive types.
Refer to a great answer by Ben Lesh for details on ngOptions as well as the ngOptions official docs.
Modify your ng-options like this:
ng-options="layout as layout.name for layout in layouts"
Your ng-options expression is in the following format:
select as label for value in array
Per angular documentation the definition of select is:
The result of this expression will be bound to the model of the parent
element. If not specified, select expression will default to
value.
You are binding the url property to the model not the whole object. That is the problem.

Changes in $http data from 1 controller to affect another in AngularJS?

So if my data is coming from a json $http, how do i make it so that if i click vote on one controller, it will sort the order by votes on another controller?
What I have so far isnt working correctly and it seems like the shared data does catches any changes between controller... take it look
app.controller('voteController', function ($scope, musicData) {
musicData.getMusic().then(function(data){
$scope.music = data.data;
});
$scope.upVote = function(music) {
music.likes++;
};
$scope.downVote = function(music) {
music.dislikes--;
};
});
// controller for top 5 charts
app.controller('topFiveController', function ($scope, musicData) {
musicData.getMusic().then(function(data){
$scope.music = data.data;
});
$scope.sortorder = '-likes';
});
// factory to share data between controllers
app.factory('musicData', function($http) {
var factory = {};
factory.getMusic = function() {
return $http.get('app/data/music.json');
};
return factory;
});
and this is what I have in the mark up
<div id="topMusic" ng-controller="topFiveController" ng-model="sortorder">
<h3 class="title"><i class="fa fa-hand-o-right"></i> Top 5 titles</h3>
<ul>
<li ng-repeat="music in music.music | orderBy:sortorder | limitTo: 5">
{{music.artist}} - "{{music.title}}"
</li>
</ul>
</div>
<div id="voteMusic" ng-controller="voteController">
<h1>Vote here</h1>
<ul>
<li class="likeMe" ng-click="upVote(music)">
<i class= "fa fa-thumbs-up" ></i> like - {{music.likes}}</li>
<li class="dislikeMe" ng-click="downVote(musics)">
<i class="fa fa-thumbs-down"></i>dislikes -
{{music.dislikes}}</li>
</ul>
</div>
this is how the json file looks like
{"music": [
{
"artist": "Artst 1",
"title": "title one",
"likes": 10,
"dislikes": 1
},
{
"artist": "Artst 2",
"title": "title 2",
"likes": 5,
"dislikes": 1
},
{
"artist": "Artst 3",
"title": "title 3",
"likes": 3,
"dislikes": 1
},
{
"artist": "Artst 4",
"title": "title 4",
"likes": 2,
"dislikes": 1
},
{
"artist": "Artst 5",
"title": "title 5",
"likes": 1,
"dislikes": 1
}
]
}
From the looks of it, you will actually need to use $rootScope.$broadcast instead of $scope.$emit, as sma suggested. As you have your markup, voteController is not actually a child of topFiveController. In your voteController, you will need to inject $rootScope as a dependency, and then use:
$rootScope.$broadcast('vote');
and in topFiveController:
$scope.$on('vote', function () {
// sort
});
If you want to update the music object in topFiveController to show the new vote without having to get from the music service again, you can also do this in your voteController:
$rootScope.$broadcast('vote', $scope.music);
then do this in your topFiveController:
$scope.$on('vote', function(music) {
$scope.music = music;
// sort
});
You can emit an event from your voteController:
$scope.$emit("vote");
and then listen for that event in your topFiveController:
$scope.$on("vote", function () {
// sort
});
I am using $emit because that will send events up the $scope inheritance tree. According to your markup, it looks like voteController is a child scope of topFiveController. If they are sibling scopes or if the topFiveController is a child scope of voteController, then use $scope.$broadcast instead of $emit. $broadcast sends events down the inheritance tree.

JSON Angular Array pulling data from 3rd Loop

I am struggling to pull the data from the 3rd loop (Names) in the array below.
Any idea what i am doing wrong?
sample.json
{
"otc": [
{
"name": "Tums",
"language": [
{
"title": "English",
"names": [
{"name": "Tums"},
{"name": "Pepto"}
]
},
{
"title": "China"
},
{
"title": "Germany"
}
,
{
"title": "Mexico"
}
,
{
"title": "India"
}
,
{
"title": "United Kingdom"
}
]
},
{
"name": "Dramamine",
"language": [
{
"title": "title2album1"
},
{
"title": "title2album2"
},
{
"title": "title2album3"
}
]
}
]
}
And this is my index.html
<body ng-app="list">
<div ng-controller="ListCtrl">
<ul>
<li ng-repeat-start="meds in otc">
<strong> {{meds.name}}</strong> //This displays just fine
</li>
<li ng-repeat="lang in meds.language"><em>{{lang.title}}</em></li> //This displays just fine
<li ng-repeat-end ng-repeat="drugs in lang.names">{{drugs.name}}</li> //This doesnt display
</ul>
</div>
<script>
angular.module('list', []);
function ListCtrl($scope, $http) {
$http({method: 'GET', url: 'sample.json'}).success(function(data) {
$scope.otc = [];
angular.forEach(data.otc, function(value, key) {
$scope.otc.push(value);
});
$scope.isVisible = function(name){
return true;
};
});
}
</script>
It looks like your JSON data is a bit incomplete, since you're missing the names key in all of the language objects except for the English one.
Beyond that, your html/angular-view code is a bit off. The ng-repeat's should be nested inside of one-another. This is done by having the opening/closing html tags that contain the ng-repeat directive completely surround the inner <li> tags.
It's a bit hard to tell, but if you want nested lists, you need to add <ul> tags like in my example below.
I believe your index html should look something like:
<ul>
<li ng-repeat="meds in otc">
<strong> {{meds.name}}</strong> //This displays just fine
<ul>
<li ng-repeat="lang in meds.language">
<em>{{lang.title}}</em>
<ul>
<li ng-repeat="drugs in lang.names">{{drugs.name}}</li>
</ul>
</li>
</ul>
</li>
</ul>
The reason why the li ng-repeat tags should be nested is because ng-repeat creates its own isolate scope. Which means that inside of an ng-repeat tag, it only has access to the data made available by the ng-repeat="data in datar" part.
So having:
<li ng-repeat="lang in meds.language"><em>{{lang.title}}</em></li> //This displays just fine
<li ng-repeat="drugs in lang.names">{{drugs.name}}</li> //This doesnt display
as sibling elements, and not the second as a child of the other, the 2nd ng-repeat list does not know what the var lang is. So the drugs in lang.names fails.
Btw, this snippet assumes that the output you want is:
Tums
English
Tums
Pepto
China
Germany
etc
Dramamine
title2album1
title2album2
etc
If you wanted the output as a flat list, you can use the following CSS
ul ul {
padding: 0;
margin: 0;
list-style-type: disc;
}

Resources