Angular JS === comparison not working - javascript

I am trying to compare the value passed from the url to a controller to a field in a json file.
galleryItem.html
<div class="filter-box">
<ul class="filter list-inline text-center" ng-repeat="gal in ParentData">
<li></li>
</ul>
</div>
<div class="container-fluid">
<div class="row">
<div class="portfolio-box" ng-repeat="x in data">
<div class="col-sm-4">
<div class="item-img-wrap">
<img ng-src={{x.url}} class="img-responsive" alt="">
<div class="item-img-overlay">
<a href={{x.url}} class="show-image">
<span></span>
</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
The updated controller:
controllers.controller('GalleryViewCtrl', function GalleryViewCtrl($scope, $http, $stateParams) {
$scope.pageName = '';
$scope.Description = '';
$scope.GalleryID = $stateParams.id;
$http.get('/data/galleryItems.json')
.then(function (response) { $scope.ParentData = response.data.galleries });
$http.get('/data/galleryItemImages.json')
.then(function (response) {
$scope.data = response.data.images.galleryIdentifier === $stateParams.id;
});
});
I verified the correct value is being passed in to the controller, the values are static and so is the data being passed from the json file. I placed an if statement to check for null as suggested as well. I removed it temporarily to reduce what I'm working with.
If I remove the === $stateParams.id i get all of the images returned and displayed correctly.
If I replace $stateParams.id with a value that I know is in the list (4 or '4') i do not get anything returned. I also tried the value for the last item in the list.
There are no errors (loading scripts, reading json etc.) and all of the values are correct when I'm debugging.
I am still new to this and there is so much documentation with different solutions it all gets very confusing. If anyone has any ideas they would be greatly appreciated.

You are loading data to the $scope.data when the ajax call returns some data. I am assuming your view code is calling the galleryFiltered even before that. May be try to add a null check before returning the value from the method.
$scope.galleryFiltered = function () {
if($scope.data!=null)
{
return $scope.data.galleryIdentifier === $scope.GalleryID;
}
return false;
};

Remember that $http service returns a promise so your $scope.data will be undefined (or holding current state) until $http.get('/data/galleryItemImages.json') will return a success callback function and assign new value to $scope.data from response.
If you'll run $scope.galleryFiltered() before promise gets resolved you will have $scope.data == undefined or whatever data is stored on $scope.data at the time or $scope.galleryFiltered() execution.

Related

Angular View not updating after retrieving data from database

I am currently working on an app that retrieves data on the of change of $routeParams. So here's how it begins:
function artistCtrl($scope, $http, $location, dataFactory, $routeParams){
$scope.artistName = $routeParams.artistname
$scope.$watch('artistName', function(newValue, oldValue){
$scope.artistInfo = dataFactory.getArtist(newValue)
})
$scope.artistInfo = {
artist_name: dataFactory.artistInfo.artist_name,
artist_genre: dataFactory.artistInfo.artist_genre,
artist_imageurl: dataFactory.artistInfo.artist_imageurl,
artist_bio: dataFactory.artistInfo.artist_bio
};
}
The callback for $watch here is run. dataFactory.getArtist retrieves newValue from my database which is being done successfully. That is done like this:
dataFactory.js
dataFactory.getArtist = function(artist){
return dataFactory.checkDb(artist).then(function(dbData){
if(dbData.data != "No data"){
dataFactory.artistInfo = dbData.data[0]
}
return dbData.data[0]
})
}
dataFactory.artistInfo = "";
dataFactory is a factory I created in another file.
artistpage.html
<div class="container this">
<div class="row">
<div class="col-sm-6">
<div><h1>{{artistInfo.artist_name}}</h1></div>
<div rate-yo id='stars' rating="myRating" class="col-sm-4"></div>
<div id='reviews'>23 Reviews</div>
<div><h2>{{artistInfo.artist_genre}}</h2></div>
<div><p>{{artistInfo.artist_bio}}</p></div>
<div><button type="button" class="btn btn-primary" ng-click="somefunc()">Submit a Review</button></div>
</div>
<div class="col-sm-6 reviews">
<div><img class="artistpageimage" src={{artistInfo.artist_imageurl}}></div>
</div>
</div>
</div>
I don't understand why my view isn't being updated. I am attempting to update $scope.artistName by assigning the returned dataFactory.getArtist(newValue)
and also by assigning the new data to dataFactory.artistInfo I have read about $apply, but I am having a hard time figuring out how to apply it in this context. Can anyone help?
Does getArtist return a promise or a value. If it's a promise try something like the below:
$scope.$watch('artistName', function(newValue, oldValue){
dataFactory.getArtist(newValue).then(function(value) {
$scope.artistInfo = value;
})
})
I think the problem is that dataFactory.getArtist(newValue) is returning a promise, which you're assigning directly to artistInfo. Try replacing it with:
dataFactory.getArtist(newValue).then(function (info) {
$scope.artistInfo = info;
});

AngularJS scope in function does not seem to be working

I have two ajax calls. The data starts from the html (input), when enter is pressed, what is in the input field is sent to the controller then to the factory which makes the first ajax call. The success is handled back in the controller, then another ajax call is requested, and the data from that request is handled back in the controller again. I have a $scope -- $scope.ytChannel = data.items; in that final success within the function that does not seem to be working. Here is my code starting with the html
HTML:
<input class="form-control channel-index" type="text" ng-model="channel" placeholder="Enter Channel" ng-keydown="$event.which === 13 && cname(channel)"/>
JS:
.factory('ytVids', function($http){
return{
getChannel: function(name){
var url = 'https://www.googleapis.com/youtube/v3/channels? part=contentDetails&forUsername='+ name +'&key=[my api key]';
return $http.get(url);
},
getVids: function(channel){
return $http.get('https://www.googleapis.com/youtube/v3/playlistItems?part=snippet%2CcontentDetails&maxResults=50&playlistId='+channel+'&key=[my api key]');
}
};
})
.controller('MainCtrl', function ($scope, ytVids) {
$scope.cname = function(channel){
ytVids.getChannel(channel).success(function(response){
//console.log(response);
console.log(response.items[0].contentDetails.relatedPlaylists.uploads);
ytVids.getVids(response.items[0].contentDetails.relatedPlaylists.uploads)
.success(function(data){
console.log('in success');
console.log(data.items);
$scope.ytChannel = data.items; // This is the scope that is not seeming to want to work.
});
});
};
});
And here is the html that calls that ytChannel
<ul>
<li ng-repeat="item in ytChannel" class="col-xs-12 col-sm-6 col-md-4 vid-options">
<a href="#">
<div class="title">{{item.snippet.title}}</div>
<img src="{{item.snippet.thumbnails.maxres.url}}" />
</a>
</li>
</ul>
if a scope is in a function, does the html not have access to it? What can be done so I can have access to the returned data?
Error
This is the error the console gives in the dev tools GET http://localhost:9000/%7B%7Bitem.snippet.thumbnails.maxres.url%7D%7D 404 (Not Found)
The correct code is
<img ng-src="{{item.snippet.thumbnails.maxres.url}}" />
As the manual says,
Using Angular markup like {{hash}} in a src attribute doesn't work
right: The browser will fetch from the URL with the literal text
{{hash}} until Angular replaces the expression inside {{hash}}. The
ngSrc directive solves this problem.

Ng-repeat is not displaying json data

thanks advance for any support. So I have a factory that uses a post to get some data from a C# method. That all seems to be working as I can see the data in the console log when it gets returned. However, when I get the data, I can't seem to get it to display properly using ng-repeat.
I've tried a couple different ways of nesting ng-repeats and still no luck. So now I'm thinking I may have not passed the data from the call properly or my scope is off. I've also tried passing data.d to hangar.ships instead of just data. Still pretty new to angular so in any help to point me int he right direction is greatly appreciated.
app code:
var app = angular.module('shipSelection', ['ngRoute', 'ngResource']);
app.controller('ShipController', function ($scope, ShipService) {
var hangar = this;
hangar.ships = [];
var handleSuccess = function (data, status) {
hangar.ships = data;
console.log(hangar.ships);
};
ShipService.getShips().success(handleSuccess);
});
app.factory('ShipService', function ($http) {
return {
getShips: function () {
return $http({
url: '/ceresdynamics/loadout.aspx/getships',
method: "post",
data: {},
headers: { 'content-type': 'application/json' }
});
}
};
});
Markup:
<div class ="col-lg-12" ng-controller="ShipController as hangar" >
<div class =" row">
<div class="col-lg-4" ><input ng-model="query" type="text"placeholder="Filter by" autofocus> </div>
</div><br />
<div class="row">
<div ng-repeat="ship in hangar.ships | filter:query | orderBy:'name'">
<div class="col-lg-4">
<div class="panel panel-default">
<div>
<ul class="list-group">
<li class="list-group-item" >
<p><strong>ID:</strong> {{ ship.ShipID }} <strong>NAME:</strong> {{ ship.Name }}</p>
<img ng-src="{{ship.ImageFileName}}" width="100%" />
</li>
</ul>
</div>
</div><!--panel-->
</div> <!--ng-repeat-->
</div>
</div>
</div> <!--ng-controller-->
JSON returned from the post(From the console.log(hangar.ships):
Object
d: "[{"ShipID":"RDJ4312","Name":"Relentless","ImageFileName":"Ship2.png"},{"ShipID":"ZLH7754","Name":"Hercules","ImageFileName":"Ship3.png"},{"ShipID":"FER9423","Name":"Illiad","ImageFileName":"Ship4.png"}]"
__proto__: Object
As per AngularJS version 1.2, arrays are not unwrapped anymore (by default) from a Promise (see migration notes). I've seen it working still with Objects, but according to the documentation you should not rely on that either.
Please see this answer Angular.js not displaying array of objects retrieved from $http.get
What happens if you add JSON.parse(data);
If this works you should add some checks in and perhaps migrate that logic to the service. Or use $resource per the other answer.
https://github.com/angular/angular.js/commit/fa6e411da26824a5bae55f37ce7dbb859653276d

AngularJS - Cannot set scope value into template

I have following function:
$scope.setDetailToScope = function(data) {
$scope.$apply(function() {
//$scope.order = data;
$rootScope.order = data;
setTimeout(function() {
$scope.$apply(function() {
//wrapped this within $apply
$scope.order = data[0];
console.log('message:' + $scope.order);
console.log($scope.order);
});
}, 100);
});
};
"
console.log($scope.order);
Gives me values which has been set into scope.
But i cannot get these values in template.
<!-- DEBUG DIV -->
<div class="debugDiv" ng-show="$root.debugable == true">
{{columns}}
</div>
<div data-ng-controller="OrdersCtrl" ng-init="initData()">
<div id="orders_grid" >
</div>
</div>
<!-- GRID TOOLBAR BUTTON TEMPLATE -->
<script id="template" type="text/x-kendo-template">
<a class="k-button" href="\#/orders/create">Add</a>
</script>
<!-- ORDER DETAIL DIV -->
<div class="container" id="orderDetail" data-ng-controller="OrdersCtrl" ng-if="'detailSelected == true'" xmlns="http://www.w3.org/1999/html">
<!-- DEBUG DIV -->
<div class="debugDiv" ng-show="$root.debugable == true">
{{order}} <!--NOT WORKING-->
</div>
If i tried to add values into rootscope it works, but in this case i cannot get value into ng-model.
What i'm doing wrong please?
Many Thanks for any help.
EDIT:
If i tried solution wit $timeout i got on console.log($scope.order);
following object which is not passed into the template:
_events: ObjectacrCrCode: "interlos"actionName: ht.extend.initarchived: falsebaseStationInfo: ht.extend.initbsc: "bsc1"btsRolloutPlan: "plan1"candidate: "B"costCategory: ht.extend.initcreatedBy: ht.extend.initdirty: falsefacility: ht.extend.initid: 3location: ht.extend.initmilestoneSequence: undefinednetworkType: "Fix"note: "poznamka"orderNumber: 111113orderType: ht.extend.initotherInfo: ht.extend.initparent: function (){return e.apply(n||this,r.concat(h.call(arguments)))}partner: ht.extend.initpersonalInfo: ht.extend.initproject: ht.extend.initpsidCode: "psid1"sapSacIrnCode: "sap1"uid: "924c0278-88d0-4255-b8ac-b004155463fa"warehouseInfo: ht.extend.init__proto__: i
well I'm not sure why you are using a setTimeout with scope apply, to me is safer to use a $timeout since it fires another digest cycle,
try something like
$scope.setDetailToScope = function(data) {
$timeout(funtion(){
//$rootScope.order = data; try either data or data[0]
$scope.order = data[0];
},100);
};
please note that calling nested apply methods can run into some problems with the angularjs digest cycle you may get an error like "digest already in progress" so put attention to it.
NOTE:
it seems like you got some dirty data there, so try to do a map between the data and the scope
$scope.order ={};
$scope.order.uid = data.uid;
$scope.order.orderNumber = data.orderNumber //and so on
in your template try something like:
<div class="debugDiv">
<p> {{order.uid}} </p>
<p> {{ order.orderNumber}} </p>
</div>
this could be a little bit rustic but it worth to try it out.

Angular API calls and promises

I'm working on an angular app and having a difficult time with one seemly simple operation. Basically, I'm making a call to the soundcloud api, grabbing my tracks, then looping through those tracks and grabbing the iframe embed object, injecting that into the tracks object then sending that whole thing as a promise to be resolved and stored in a $scope.soundcloud object. Just fyi, the second SC call is necessary to generate the widget html. I wish it wasn't but it is hah.
This all happends as it should and i can see the object in $scope. My template picks up the initial data (main track data), and console.logging the object shows the track and embed data, but the template NEVER sees the embed data.
So, fundamentally, How do I get my template to see the embed data, so i can use it with a directive or ng-bind-html? Below is all my code, please ask if you need any more information! Thank you all very much.
HTML
<div class="track" ng-repeat="track in soundcloud.tracks">
<div class="front">
<img src="app/img/loading.gif" />
</div>
<div class="back" ng-bind-html="{{track.oembed}}">
</div>
</div>
Angular Service
getTracks: function(){
var deferred = $q.defer();
var promise = deferred.promise;
SC.get("/me/tracks", function(tracks){
$.each(tracks, function(k, v){
if(v.sharing != 'private'){
SC.oEmbed(v.uri, function(oembed){
v.oembed = $sce.trustAsHtml(oembed.html);
});
} else {
v.oembed = null;
}
});
deferred.resolve(tracks);
});
return $q.all({tracks: promise});
}
Angular Controller
.controller("GridCtrl", ['$scope', 'Soundcloud', function($scope, Soundcloud){
// Init the Soundcloud SDK config
Soundcloud.initialize();
// Get the tracks from soundcloud
Soundcloud.getTracks().then(function success(results){
// Store tracks in the $scope
$scope.soundcloud = results;
console.log(results);
});
}]);
Try creating a directive like this:
app.module('yourModule').directive('embedTrack', function() {
return function(scope, elem, attr) {
elem.replaceWith(scope.track.oembed);
};
});
You then use it like this:
<div class="track" ng-repeat="track in soundcloud.tracks">
<div class="front">
<img src="app/img/loading.gif" />
</div>
<div class="back">
<div embed-track></div>
</div>
</div>
In case you want to pass it as an attribute to the directive, you need to use attr.$observe to make sure you get the value after the interpolation.
<div embed-track={{ track.oembed }}></div>
The directive would then be:
app.module('yourModule').directive('embedTrack', function() {
return function(scope, elem, attr) {
attr.$observe('embedTrack', function(value) {
elem.replaceWith(value);
});
};
});

Categories

Resources