Im writing a backbone application where the User model has to be fetched with the data of the logged in user. In my template i need to display user information(Username, Name etc). After compiling template error message is been logged in console "Uncaught ReferenceError: username is not defined". The Ajax request is also completed successfully. What might be the problem?
Im linking my js files.
Link to js files
Even though your AJAX request succeeds, it most likely hasn't succeeded yet by the time you execute the underscore template. You call render immediately after fetch, which is an asynchronous operation. When this line of code executes, model.toJSON() call most likely returns an empty object.
You should move the fetch call to your view's initialize function like this:
initialize: function() {
_.bindAll(this);
this.model.fetch({success:this.render});
}
This will postpone the rendering until the model is successfully fetched.
Related
All:
I have an Iframe tag on a simple HTML page and inside this Iframe tag is a HTML form - lets call it a widget. Its a form where the user can enter search criteria and click on a button to obtain the search results. I have decided to use Angularjs to make the necessary DB calls to a REST service that returns the search results back to the widget for display.
In testing this I enter a value in a textbox on the widget, that value being a value that I know exists in a particular table I'm testing against.
Here is my $http get call:
$http
.get('http://localhost/XXXXService/folder/getfolders/' +
$scope.formData.srchterm **==>** mapped to search textbox
).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
//$scope.formData = response;
//$scope.nrdFolderDataArray = response;
console.log('Success retrieving data.');
console.log(response.length);
console.log('response:');
console.log(response);
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
console.log('Error occurred retrieving data.');
console.log(response.status);
console.log('returned data count:');
console.log(response.size);
console.log('response:');
console.log(response);
});
This call is inside a function called "submitForm" that is mapped to the widget with a "ng-submit="submitForm()" attribute on the submit button. And yes there are several log statements so I can try and figure out what is going on here. And what is happening is this: after entering a value in the textbox, THE FIRST TIME the search button is clicked the .get command does not work. I does not make the call to the REST service. I know this because I wrote the REST service and made sure I put in plenty of log statements while doing so and there are no log statements in the log file from the REST service. Instead the errorCallback block runs and I see all those log statements in the console. The "response" (object?) after THE FIRST call looks like this:
Object {data: null, status: 0, config: Object, statusText: ""} Method = GET Status = (canceled) type xhr
Further, in FF there is no response data to view in the Net tab of Firebug upon THE FIRST call, but there is response data to view in all subsequent calls.
So, interestingly enough each subsequent invocation of that $http.get call works! I see log statements in the log file from the REST service method and the successCallback block runs and I can see my data via those console.log messages.
Also, if I were to change the search value in the text box, which would then be THE FIRST TIME we would be searching for data for that new key, once again, the call does not work, but does work on subsequent clicks on the "search" button for that new key value.
I really am not sure if I have a CORS issue here since, other than THE FIRST calls each subsequent $http.get call works like a champ. Its just that very first call or first call after the search key has changed that the $http.get does not want to work.
I have tried setting headers in the .get call and I have tried using
#CrossOrigin(origins = "http://localhost/7001") as per
https://spring.io/guides/gs/rest-service-cors/ but I continue to have this issue on the first time invoking this .get call.
I've been dealing with this issue for way too many hours now and would sure appreciate some input as to why this is happening.
I'm sorry for being verbose here. I wanted to explain my issue thoroughly.
Please help.
Thank you
-g
I'm developing an Ionic application for the Android platform and I've ran into the following problem using Angularfire's $loaded/$watch function.
The controller uses AngularFire's $firebaseObject to retrieve student information, and then uses the $loaded function to print a message once the data is retrieved. Similarly, it uses a $watch to print a message when the data changes.
The problem is that sometimes these messages do not get printed to the console when the view is visited. Let's say neither of the messages get printed, by navigating to another controller, they get printed to the console.
Sometimes, the $loaded message will be printed, but the $watch will not be triggered when changes are made in Firebase, until we navigate away to a different controller.
Sometimes, they both work perfectly.
Once thing I've noticed is that by force stopping the application and restarting it, the application behaves as intended.
var firebaseDatabase = FirebaseService.getFirebaseDatabase();
var student = $firebaseObject(firebaseDatabase.ref('randomstudentid/'));
student.$loaded().then(function(){
console.log("The student information has been loaded.");
});
student.$watch(function(){
console.log("A watch has been triggered on the student information.");
});
Thanks in advance for your help.
I've been following this tutorial http://draptik.github.io/blog/2013/07/28/restful-crud-with-angularjs/. I implemented a Grails backend with it instead of the Java one in the tutorial.
I've got the data coming back and forth, with one issue. If I create/update/delete a user, I don't see the changes reflected on my user list when I am redirected back. I have to refresh the page to see the updates.
Looking at the network traffic for an edit, it looks like it does a PUT and fires off the GET before the PUT is complete. Assuming this is because $resource returns a promise so things can be done asynchronously. So how do I handle this so that when $location redirects me, my list is up to date?
I'm guessing the options are to wait for the PUT to complete before redirecting/querying for the list, or to somehow manually manage the $scope.users to match the request?
Or maybe this tutorial is just a bad example? Maybe there is a better way to do it (still using $resource)?
Note: I've seen Restangular out there, and I've seen $http with success callbacks, but I would like to understand the situation above.
One way to overcome this issue would be to not redirect to the list page, till you get a callback, and then do a redirect. You can show some busy indicator till that time. The resource call looks like this.
resource.update(config,data,function() { //gets called on success},
function(error) { //gets called on failure});
In real life scenario waiting for the response of update makes sense as you want to handle the error and success scenarios on the same page.
I don't see your code anywhere so i'm just assuming (based on what you wrote and your current problem)
You are probably doing a full (or partial) get each time you changed a user and (re)binding the result to your scope. Doing this in the callback of the resource should actually start the digest cycle angular does to update modified objects. If you had been doing the fetching outside $resource - for example with custom/jquery ajax you would need to execute $scope.$apply()
What i really don't understand you would need to wait for the callback. You already know you added/modified a user. Instead of 'detaching' that user from your scope, modify it, post it to your rest server, then wait for callback, and reinserting it into the scope - why not modify it directly in the list/array you put on your scope?
var users = Users.get(function () {
$scope.users = users.record; // bind the resulting records to the scope
});
$scope.updateUser = function (user) {
resource.update(...); //pseudo
};
Then in your html, you will keep a reference to the currentUser and the div-list will update automaticly.
<div ng-repeat="user in users" ng-click="currentUser=user">{{user.Name}}</div>
<input ng-model="currentUser.Name">
<button ng-click="updateUser(currentUser);">Update</button>
If you don't want to see the update in the list while you type, but only once your callback fires or when you hit the button, would would instead use another ng-model for your input like this:
<input ng-model="tempUser.Name">
And you would then copy the value other in either the updateUser method or in the resource callback like this:
$scope.updateUser = function (user) {
user.Name = $scope.tempUser.Name; // should update automaticly
resource.update(...) // pseudo
}
Hope it helped!
I'm pretty new to Angular and I'm using firebase as my backend. I was hoping someone could debug this issue. When I first go to my page www.mywebsite.com/#defaultHash the data doesn't load into the DOM, it does after visiting another hash link and coming back though.
My controller is like this:
/* initialize data */
var fb = new Firebase('https://asdf.firebaseio.com/');
/* set data to automatically update on change */
fb.on('value', function(snapshot) {
var data = snapshot.val();
$scope.propertyConfiguration = data.products;
console.log($scope.propertyConfiguration);
console.log("Data retrieved");
});
/* save data on button submit */
$scope.saveConfigs = function(){
var setFBref = new Firebase('https://asdf.firebaseio.com/products');
setFBref.update($scope.propertyConfiguration);
console.log("configurations saved!");
};
I have 3 hash routes say "Shared", "Registration", and "Home" with otherwise.redirectTo set to "Shared".(They all use this controller) Here's the error that occurs: (all "links" are href="#hashWhereever")
1) Go to website.com/#Shared or just refresh. Console logs $scope.propertyConfiguration and "Data Retrieved". DOM shows nothing.
2) Click to website.com/#Registration, console logs $scope data properly, DOM is loaded correctly.
3) Click back to website.com/#Shared, console logs $scope data properly yet this time DOM loads correctly.
4) Refresh currently correctly loaded website.com/#Shared. DOM elements disappear.
Since $scope.data is correct in all the cases here, shouldn't Angular make sure the DOM reflects the model properly? Why is it that the DOM loads correctly only when I am clicking to the page from another link.
I can "fix" it by adding window.location.hash = "Shared" but it throws a huge amount of errors in the console.
FIXED:(sorta)
The function $scope.$apply() forces the view to sync with the model. I'd answer this question myself and close it but I'm still wondering why the view doesn't load correctly when I correctly assign a value to $scope. If Angular's "dirty checking" checks whenever there is a possibility the model has changed, doesn't assigning a value to $scope overqualify?
Angular has no way to know you've assigned a value to $scope.variable. There's no magic here. When you run a directive (ng-click/ng-submit) or Angular internal functions, they all call $apply() and trigger a digest (a check of the dirty flags and update routine).
A possibly safer approach than $apply would be to use $timeout. Currently, if you call a write op in Firebase, it could synchronously trigger an event listener (child_added, child_changed, value, etc). This could cause you to call $apply while still within a $apply scope. If you do this, an Error is thrown. $timeout bypasses this.
See this SO Question for a bit more on the topic of digest and $timeout.
This doc in the Angular Developer Guide covers how compile works; very great background read for any serious Angular dev.
Also, you can save yourself a good deal of energy by using the official Firebase bindings for Angular, which already take all of these implementation details into account.
Vaguely Related Note: In the not-too-distant future, Angular will be able to take advantage of Object.observe magic to handle these updates.
I want to intercept console log message from AngularJS and display them in a div on the page. I need this in order to debug ajax traffic in a PhoneGap app.
This is an example of the kind of errors I want to capture:
I tried this Showing console errors and alerts in a div inside the page but that does not intercept Angular error messages.
I also tried the solution gameover suggested in the answers. No luck with that either. Apparently $http is handling error logging differently.
I guess the answer you tried has the right idea but you're overriding the wrong methods. Reading here I can see angularJs uses $log instead of console.log, so to intercept you can try to override those.
Something like this:
$scope.$log = {
error: function(msg){document.getElementById("logger").innerHTML(msg)},
info: function(msg){document.getElementById("logger").innerHTML(msg)},
log: function(msg){document.getElementById("logger").innerHTML(msg)},
warn: function(msg){document.getElementById("logger").innerHTML(msg)}
}
Make sure to run that after importing angular.js.
EDIT
Second guess, override the consoleLog method on the LogProvider inner class on angular.js file:
function consoleLog(type) {
var output ="";
//arguments array, you'll need to change this accordingly if you want to
//log arrays, objects etc
forEach(arguments, function(arg) {
output+= arg +" ";
});
document.getElementById("logger").innerHTML(output);
}
I've used log4javascript for this purpose. I create the log object via
var log = log4javascript.getLogger('myApp')
log.addAppender(new log4javascript.InPageAppender());
I then use this in a value dependency, and hook into it where needed (e.g. http interceptor).
A more lightweight approach might be to use $rootScope.emit and then have a component on your main page which prepends these log messages to a visible div, but this will require you to change all your calls to console.log (or redefine the function in your js).
I think that this message is not even displayed from AngularJS. It looks like an exception which has not been caught in any JavaScript (angular.js just appears on top of your stack because that's the actual location where the HTTP request is being sent).
Take a look at ng.$exceptionHandler. That should be the code you seem to be interested in. If not, take a quick web search for „JavaScript onerror“ which should tell you how to watch for these kinds of errors.
I would rather user an $http interceptor.
Inside the responseError function, you can set a property on a service that will be exposed to the div's scope.