AngularJS binding not occurring on page until a user action - angularjs

I've got my first angular app which displays some data from a list via ng-repeat.
The controller for the view sets a few variables to scope - some directly in the function and another from an API call.
The data from the in function load is showing up in that ng-repeat. The data from the service call doesn't show up (debugging shows the function is being called and data returned and set in scope).
I've got a filter on and if I type anything in it then the data shows up. Or when I click to another view the data flashes onto the page briefly before it loads the new view.
Here is some view code (the items works, venues does not):
<div ng-repeat="item in items">
{{ item.firstName }}
</div>
<div ng-repeat="venue in venues">
{{ venue.details }}
</div>
And here is the controller (data is coming back from the call):
$scope.items = [
{ "firstName": "John", "lastName": "Doe" },
{ "firstName": "Anna", "lastName": "Smith" },
{ "firstName": "Peter", "lastName": "Jones" }
];
var client = new WindowsAzure.MobileServiceClient("url", "key");
var query = client.getTable("venues").read().done(function (results) {
$scope.venues = results;
}, function (err) {
alert("Error: " + err);
});
I'm wondering if maybe the binding is happening before the data is returned from the API?
I added a div and this line into the function and it is printing the results to the page no issues:
document.getElementById("venueslist").innerHTML = JSON.stringify(results);
Thank you for reading.

Looking at your code client.getTable doesn't look like it is using any of angularJs $http or $timeout service. So you will have to wrap the assignment in scope.$apply() so that the $digest cycle is run and the bindings are updated in the view.
var query = client.getTable("venues").read().done(function (results) {
$scope.$apply(function () {
$scope.venues = results;
});
}, function (err) {
alert("Error: " + err);
});
Side note: why are you doing JSON.parse(JSON.stringify(results)), you can directly use results if it is a json object.

Related

How to convert string into JSON data in view part of angularjs

Hi I have this data in JSON form, and I want to convert this data of option into json so that i can call optionName, optionSubName in a view part of angularjs
[
{
"heading": "MakeUp Type / Selection",
"option": "{"optionName":"Bridal Makeup","optionSubName":"Engagement,Tika / Godh Bharai,Ring Ceremony","optionDesc":""}",
"values": null
},
{
"heading": "Makeup Type",
"option": "{"optionName":"Experienced","optionSubName":"","optionDesc":{"products":"Bobbie Brown,Makeup Forever and Premium Makeup Products","Makeup_Include":"Straightening,Blow Drys,Tong Curls,Updo's","Drapping":"Yes","Lashes":"Yes","Nail_Polish_Change":"Yes","Extension_Available":"Yes","Airbrush_Available":"Yes"}}",
"values": null
}
]
I have already tried this but this is not working by using ng-repeat i have using this {{data.option.optionName | JSON}} but this is not working in my view part of angularjs, Please help me out how to reach at my goal ?
Use AngularJS forEach:
angular.forEach(object, iterator, [context])
object: The object interate over.
iterator: The iterator function or the code.
context: Object to become context (using this) for the iterator function.
var app = angular.module('app', []);
app.controller('AppController', ['$scope', '$http',
function($scope, $http) {
$http.get('json/array.json').success(function(data) {
$scope.array = data;
angular.forEach($scope.array, function(x){
console.log(x.optionName);
})
});
});
}
]);

update the json after delete some data inside it

I try to learn angular. currently, i already get data from JSON ( i use local JSON). I try to delete 1 of an array from JSON, its works but after I refresh the page the deleted array come back again. how to update the JSON after I delete array?
customer.html
<tr ng-repeat="experience in experiences">
<td>{{experience.no}}</td>
<td>{{experience.name}}</td>
<td><button ng-click="deleteItem(experience)" class="btn btn-danger">-</button></td>
</tr>
main.js
resolve:{
experiences:['$http',function($http){
return $http.get('scripts/customer.json').then(function(response){
return response.data
})
}]
}
customer json
[
{
"no":1,
"name": "Sarah",
},
{
"no":2,
"name": "Tommy",
}
]
customerCtrl.js
angular.module('app').controller('customerCtrl',['$scope','experiences',function($scope,experiences){
$scope.experiences= experiences;
$scope.deleteItem =function(experience){
var index = $scope.experiences.indexOf(experience);
alert("Deleting DATA: "+ index);
$scope.experiences.splice(index,1);
};
}]);
You're trying to store data in a file using javascript, which is considered as insecure and then hard to implement.
I would suggest you to use LocalStorage instead. Here is a service example you could use in your controller (not tested)
localstorage service
angular.module('app').service('LocalStorage', function(){
return {
save: function(data) {
localStorage.setItem('data',data);
},
get: function(){
return localStorage.getItem('data');
}
};
});
controller
// notice that I injected LocalStorage in controller
angular.module('app').controller('dataPengalamanCtrl',['$scope','experiences',function($scope,experiences, LocalStorage){
$scope.experiences= experiences;
$scope.deleteItem =function(experience){
var index = $scope.experiences.indexOf(experience);
alert("Deleting DATA: "+ index);
$scope.experiences.splice(index,1);
// First transform you're json to a string
var stringifiedData = JSON.stringify( $scope.experiences);
// from there we save data to localStorage
LocalStorage.save(stringifiedData );
};
// if you need, you can load data using :
$scope.data = LocalStorage.get();
Dont forget to save your json in localstorage first, for example with a file like this one :
init.js
var json = [
{
"no":1,
"name": "Sarah",
},
{
"no":2,
"name": "Tommy",
}
];
var strData = JSON.stringify(json);
localstorage.setItem('data', strData);
EDIT
If you want to go with a remote server like myjson.com
Assuming you already saved your json on myjson.com, and url is https://api.myjson.com/bins/8hghd then :
To retrieve your json use $http.get('https://api.myjson.com/bins/8hghd').success(/*...*/).error(/*..*/);
To update your json use $http.put with your json as data (grammar depending of your AngularJS version, see here)
Have a look to the api documentation : http://myjson.com/api

In AngularJS, $http doesn't change my select option tag data

I have an issue in AngularJS on using $http to fetch data from server.
Here is my HTML
<select ng-model="foo" ng-options="item as item.name for item in items"></select>
Here is my AngularJS Script
angular.module("myApp").controller("myCtrl", function($scope, $http) {
var $scope.items = [];
$scope.items = [
{
"id": 1,
"name": "item1"
},
{
"id": 2,
"name": "item2"
},
];
getData();
function getData() {
$http.get("ng/getData")
.then(function(response) {
if (response.status == 200) {
$scope.items = response.items;
/*
$scope.items = [
{
"id": 5,
"name": "item11"
},
{
"id": 4,
"name": "item22"
}
];
*/
}
});
}
});
What expect from this code is when $http fetches data from server, then select dropdown data will change. But it's not changing anything. I have also printed the response items in the console inside the success callback.
Maybe I don't understand $http usage well enough. Perhaps when I console out data after getData(); $scope.items doesn't change at all. And I think that maybe $http always run at last stage.
Can anybody help to explain this issue? If my assumption is correct, what is the solution that I am looking for?
I think you simply have to add a track by clause:
ng-options="item as item.name for item in items track by item.id"
Check the response object. When you are using 'then' callback to get the resolved data then the actual API result is stored in the 'data' property of the response. So change your code to
$scope.items = response.data;
Or you can use the success callback to attach the data directly.
$http.get("ng/getData")
.success(function(response) {
if (response.status == 200) {
$scope.items = response.items;
}
});

ng-view not updating upon ng-click

I am using ng-view within my Angular application. within index.html I have a button, When I click on this button I am getting the JSON data, however I cant access my updated scope back into my ng-view template. please examine the code below.
<
div class="row" style="display:none;" id="srhBox" ng-controller="SearchController">
<button
data-channelid="" data-relatedtovideoid="" data-videoduration="" data-videotype="" data-keyword="{{keyword}}"
ng-click="search($event)" class="btn btn-default" type="submit">
</div>
Here is controller
angular.module('kZoneApp').controller('SearchController', ['$location','$scope', 'dataFactory', '$window', '$routeParams', '$rootScope','$http', function ($location,$scope, dataFactory, $window, $routeParams, $rootScope, $http) {
$scope.search = function (evt) {
$location.path("search"); // update ng-view
var keyword = $(evt.currentTarget).attr("data-keyword");
var channelid = $(evt.currentTarget).attr("data-channelid");
var relatedtovideoid = $(evt.currentTarget).attr("data-relatedtovideoid");
var videoduration = $(evt.currentTarget).attr("data-videoduration");
var videotype = $(evt.currentTarget).attr("data-videotype");
var url = 'http://xxxx.com/api/Videos/Search?'
url = url + 'keyword=' + keyword
url = url + '&channelid=' + channelid
url = url + '&relatedtovideoid=' + relatedtovideoid
url = url + '&videoduration=' + videoduration
url = url + '&videotype=' + videotype
$http.get(url).
success(function (data) {
$scope.searchResults = data;
console.log(data) // Yes it shows JSON data
});
}
}]);
and here is code for ng-view template...
<div class="col-md-12 " style="padding-top:5px;">
{{searchResults.nextPageToken}} // This is BLANK
</div>
json....
{
"nextPageToken": "CBkQAA",
"items": [
{
"etag": "\"dhbhlDw5j8dK10GxeV_UG6RSReM/B_XTRBSSmBkwVbCPVJmABe4rJpo\"",
"id": {
"kind": "youtube#video",
"videoId": "n8JEY8PKCcI"
},
"snippet": {
"publishedAt": "2015-06-05T18:51:06.000Z",
"channelId": "UCY48IObMpigEGsBEtfUUepg",
"title": "WWE 2K15 The New Day vs Power Rangers Summer Slam wwe 2k15",
"description": "I created this video with the YouTube Video Editor (http://www.youtube.com/editor)",
"thumbnails": {
"default": {
"url": "https://i.ytimg.com/vi/n8JEY8PKCcI/default.jpg"
},
"medium": {
"url": "https://i.ytimg.com/vi/n8JEY8PKCcI/mqdefault.jpg"
},
"high": {
"url": "https://i.ytimg.com/vi/n8JEY8PKCcI/hqdefault.jpg"
}
},
"channelTitle": "Caqueen520",
"liveBroadcastContent": "none"
}
},..... more items
route config.
$routeProvider
.when('/search', {
templateUrl: 'pages/search.html',
controller: 'SearchController'
})
so {{searchResults.nextPageToken}} is empty, even though console.log clearly shows it has value. what could be causing this.
UPDATE
it seems like the problem is.... I have ng-controller="SearchController" for my button and then i am loading the VIEW (ng-view) using the routes, so angular does not update two controllers with same name on the same page....it updates the first controller & ignores the second one.
Though $http takes care of running digest cycle which takes care of two way biding, try adding a timeout using $timeout because it also runs the digest cycle.
$http.get(url)
.success(function (data) {
$timeout(function () {
$scope.searchResults = data;
console.log(data) // Yes it shows JSON data
}, 100);
});
As per your route config, /search view uses the same controller SearchController. So when you load the /search view using $location.path('/search') the controller is reinitialized so $scope.searchResults will be undefined. You will have to have to search login inside a different controller and use that controller in the route config.
OR you can have a hidden partial view and show it only when you have the searchResults using ng-if directive.
So in the main view have this html
<div ng-if="searchResults" class="col-md-12 " style="padding-top:5px;">
{{searchResults.nextPageToken}} // This is BLANK
</div>
And remove the $location.path('/search') from $scope.search method in the SearchController.

Firebase retrieve data shows only one result

I am trying to retrieve a data of objects and the result shows on the console but it only shows one result(the last result) on the page.
$http.get('/users').success(function(data) {
$scope.username = data; //assign data to username
console.log(data);
});
And in my Jade template, i have
section(data-ng-controller='browse')
h4 hi
ul(data-ng-repeat='user in username')
li {{user}}
I want to loop through this data
{
"google: xxxxxxxxxxxxx" : {
"name" : "ZZZ YYY",
"profile" : {
"briefProfile" : "Cost call",
"career" : "Web Developer",
"projects" : {
"-JjtSgiwkqFxTxMv0Gip" : "http://zipper.com"
}
},
"provider" : "google"
},
"google:xxxxxxxxxxx" : {
"name" : "SSS TTT",
"profile" : {
"briefProfile" : "Desired Intelligence",
"career" : "Consultant"
},
"provider" : "google"
}
}
Thanks.(i'm not using angularFire).
If you're using the $http service, then you're not using Firebase.
You are repeating the ul instead of the li. Also, {{user}} will be the whole user object, and you will see something like [Object object] on your page instead of a string. So call {{user.name}}.
ul
li(data-ng-repeat='user in users') {{user.name}}
Assuming that $http is there by mistake, and you meant to use Firebase instead, you probably want to start by reviewing the Firebase Getting Started guide
// Get a reference to users
var ref = new Firebase('https://<YOUR-FIREBASE>.firebaseio.com/users');
// Attach an asynchronous callback to read the data at users ref
ref.on("value", function(snapshot) {
console.log(snapshot.val());
$scope.users = snapshot.val();
}, function (errorObject) {
console.log("The read failed: " + errorObject.code);
});
If you're using AngularFire you should take a look at this:
Instead of using $http.get try:
var data = $firebaseArray(new Firebase("URL"));
$scope.data = data;
Don't forget to add $firebaseArray as a dependency in your controller.
More info on AngularFire docs:
https://www.firebase.com/docs/web/libraries/angular/api.html#angularfire-firebasearray
If you're not using AngularFire take a look at this:
var firebaseRef = new Firebase('YOUR-FIREBASE-URL/users/');
firebaseRef.on('value', function(dataSnapshot) {
var data = dataSnapshot.val();
console.log(data);
$scope.users = data;
// Might need to use $digest to update $scope.
$scope.$digest();
});
More about on() in Firebase docs:
https://www.firebase.com/docs/web/api/query/on.html

Resources