How to avoid angular.js preemptively fetching data until certain actions - angularjs

Just started out using angular.js and implemented a directive that reads from a property in the scope that's defined only when a button is clicked. The UI looks fine also because the directive part is only shown when the button is clicked. However in the console when the page is first loaded there is an error message saying "Cannot read property someProperty of undefined".
I must be violating some angular principles but I'm not sure how to fix it. Thanks for the help!
Note: Didn't do a fiddle because this is a general question.

Generally speaking, if you have code patten like
$scope.myObject.property
then you could see the error when myObject is undefined.
One possible way to eliminate the error the code work is make sure the object is always initialized when any property is intended to be referred.
You can put this line before the property is referred.
$scope.myObject = {};
Or do
if($scope.myObject !== undefined){
...
}
There is no rocket science here.

Related

TyperError: Cannot read property 'length' of undefined

Our team is using angularjs to develop a ServiceNow widget and we are seeing "TyperError: Cannot read property 'length' of undefined" in our console:
When we click on "at eval", it takes us to this particular snippet of code with line 321 highlighted:
We can't seem to figure out what's causing that error. We are using $watch on an array ($scope.data.list) and have read that $watchCollection might be better, but we tried that with no change. Any ideas what could be causing this error and how to get rid of it?
From the code you have posted, you haven't defined or nor declared
$scope.data.list (I'm assuming $scope.data is defined somewhere). To
resolve that, you need to at least declare your $scope.data.list first to watch over it.
Coming to the $watch part, it depends on what your requirement is.
$scope.$watchCollection looks for changes made in the array as well as elements whereas,
$scope.$watch will only look for changes made if the array is totally
assigned to a different one. Otherwise, if you want to watch deep, you can
use $scope.$watch with a boolean true variable passed as a third
argument to it.
Refer this link for the full documentation - https://www.sitepoint.com/mastering-watch-angularjs/
As of my knowledge $watch on $scope.data.list called whenever any value changed in this collection
So by looking at error it seems like $scope.data.list list in no longer exits in $scope.data. Try to find out where $scope.data is going to change.
And use below syntax for watch on collection
$scope.$watchCollection('names', function(newList,oldList) {
if(newList && newList.length) {
$scope.data.list = newList.length;
}
});

$uibModal TypeError: Cannot read property 'close' of undefined

I am working in ServiceNow and have a button that pulls up a modal window that renders an embedded form. When a user submits, I have the embedded form $broadcast 'closeModal', and the button receives it to close. My client script looks like this for the embedded form:
$rootScope.$broadcast('closeModal');
and on my button that brings up the modal, my client script looks like this:
$rootScope.$on('closeModal', function() {
c.modalInstance.close();
});
This actually does close the modal window, but my console is showing "TypeError: Cannot read property 'close' of undefined"
Any idea why this is showing up?
Additionally, in my screenshot above, that typeerror actually shows up twice, for two different widgets. I am broadcasting and retrieving the same event for both widgets. I'm not sure if that's against best practice, but I've tried changing one of them to 'closeModal2' for example and the same typeError still shows.
Any suggestions or advice is greatly appreciated!
-- ADDED --
This is a screenshot of my console after logging c:
Simple hack is :
$rootScope.$on('closeModal', function() {
c.modalInstance && c.modalInstance.close();
});
Another suggestion is use $rootScope.$emit and listen at specific scope level $scope.$on

Refreshing translations using angular-translate

I'm using angular translate for i18n.
The particular feature I'm working on is updating the status of a book. In the service callback, if successful, I am updating my book status from, say, Open to Closed. If I view the scope (using Batarang), I can see my DOM element as such:
<span translate="Closed" class="ng-scope">Open</span>
As you can see, the translate value is being updated, but the translation itself isn't occurring on its own. I've read the docs and understand this is expected behavior. What I want to know, though, is how should I be refreshing the translated value?
Presently, I'm injecting the $translate service and executing $translate.refresh() every time I update a scope value that needs to be re-translated. I feel like that's clunky, and probably not the way I should be doing it.
Any thoughts?
You definitely should not issue a refresh for this.
just do something like this:
<span> {book.state | translate} </span>
Given that your book model has a member state to reflect it's state.
Whenever the model changes, the value of state will be re-translated.
Create a common service for translation, this will configure our translation code, in particular it will configure the location of our translation files. Create a directory src/common/translation, and a file src/common/translation/translation.js:
http://technpol.wordpress.com/2013/11/02/adding-translation-using-angular-translate-to-an-angularjs-app/
angular.module('angularTranslateApp', ['pascalprecht.translate'])
.config(function($translateProvider, $translatePartialLoaderProvider) {
$translateProvider.useLoader('$translatePartialLoader', {
urlTemplate: '/UI/assets/translation/{lang}/{part}.json'
}
});
$translateProvider.preferredLanguage('en-AU'); });

Creating a custom Store in a view initComponent yields to "Uncaught TypeError: Cannot read property 'apply' of undefined"

I have been using extjs for only 3 days now so I am very new and am trying to get used to some of the concepts.
I have a view called GroupListView which contains multiple GroupViews. Each group view needs to instantiate a ContactStore and invoke an ajax call with the groupId to get all the contacts in that group. So, I thought I can put a var contactStore = Ext.Create('MyApp.store.ContactStore'); in to the initComponent of the GroupView component (remember I don't want a singleton - each group has its own contact data).
It throws an "Uncaught TypeError: Cannot read property 'apply' of undefined" error when I do that. If you remove that line things are fine but obviously I have no contact data.
https://fiddle.sencha.com/#fiddle/5gv
What am I doing wrong? And once I get this working, what is the best practice to get the groupId from the GroupView in the example (so I can pass it in the ajax call to the restful service)? Is it to set a local property, like I do, called groupData in the GroupStore load loop I have? Is there a better way to automatically create a GroupView components for all the items in the GroupStore, like a repeater kind of thing, rather than my manual loop?
If you can kindly just give me a general "yes - you're on the right path" or "no you're doing things not the extjs way" I'd appreciate it. Yes - I realize I am missing controllers :)
Thanks

Backbone.js model not defined in view?

I've decided that I am going to try and learn backbone.js by making a web app. This is the first time I have done anything extensive in javascript, so the answer to my problem may be right in front of my face.
I have the web app on github, along with a running version that doesn't work. The javascript console just says that something is undefined when I don't think it should be. Here's the error that chrome gives for line 30 of app.js:
Uncaught TypeError: Cannot read property 'el' of undefined
I've sort of been referencing the backbone-fundamentals example modular to-do app, and it doesn't seem to have any issues with a similar thing.
If anyone could point out what I am doing wrong, I would be most appreciative!
Thanks in advance!
Your Machine view render method was missing return this and by default all methods return undefined - that's why chaining didn't work
Edit: and a small tip:
jQuery, Underscore and Backbone register globally - and thanks to that you don't have to define them as dependencies every time - it's enough if you require them in your main script once and after that you can access them from the global scope as you normally would
In my case i was returning this without the return keyword. As i was using javascript and not coffeescript it failed on me. So, if you are using javascript use return this; instead of just this in the last line of the render() function.
I also had a problem when using this.collection.on('reset', this.render(), this). I instead had to use this.collection.on('reset', this.render.bind(this));

Resources