AngularJS querySelector by ID Returns Undefined - javascript

Here is what my index.html looks like:
And this is the Javascript code (angular):
var controllerElement = document.querySelector('[id="tile3"]');
console.log(controllerElement.getAttribute('class'));
var controllerScope = angular.element(controllerElement).scope();
As you can see, I'm trying to find the controllerElement by searching for an id equal to tile3. However, whenever I get to the next line the program crashes with this error:
Uncaught TypeError: Cannot read property 'getAttribute' of null
Is there something obvious I'm missing?
EDIT
Here is the full code, now the controllerScope var is being undefined for some reason...
var update = function(id, channel){
var controllerElement = document.querySelector('#tile3');
console.log(controllerElement.getAttribute('ng-controller'));
var controllerScope = angular.element(controllerElement).scope();
console.log(controllerScope);
controllerScope.$apply(function () {
controllerScope[id].username = channel.username;
controllerScope[id].keyword = channel.keyword;
controllerScope[id].percent = channel.percent;
controllerScope[id].views = channel.views;
controllerScope[id].link = channel.link;
});
};
(function(){
var app = angular.module("testApp", []);
var TileController = function($scope){
$scope.channels = [];
for(i = 0; i < 25; i++){
var channel = {
username:"John",
keyword:"Doe",
percent:"50%",
views:5000,
link:"http://www.twitch.tv/lolyou"
};
$scope.channels.push(channel);
}
};
app.controller("TileController", ["$scope", TileController]);
update(3, {username:"Yo",
keyword:"Bro",
percent:"40%",
views:35,
link:"http://www.twitch.tv/nickbunyun"});
})();
The line where it says console.log(controllerScope); is just printing "undefined".

If you are using querySelector then you could/should just use #tile3 as value passed to the function, so:
var tile3 = document.querySelector('#tile3')

Related

How do you populate a dynamic variable in AngularJS

The following code gives me the error "Cannot read property PERSON1 of null". If I comment out the line where I try to assign the dynamic variable and uncomment the alert line it pops up alerts with each successive person's name.
function fillInternalRepData() {
var internalRepList = null;
console.log("Querying Table for internal reps");
queryTable(//..blabla..//, "false", function (callbackResp) {
internalRepList = callbackResp;
// alert("TRIGGERED"); //WORKS
// alert(internalRepList.length); //WORKS
angular.forEach(internalRepList, function (rep) {
repName = rep.such;
$scope.internalReps[repName].such = repName;
//alert(repName); //WORKS WHEN LINE ABOVE IS COMMENTED OUT
});
}); //get list of internal reps
I simply want to create/add to the $scope.internalReps object so that I can add stuff to it like $scope.internalReps.PERSON1.Name = "Whatever"; $scope.internalReps.PERSON1.Salary = 100000;
Try adding an empty object for the "internalReps" before your forEach loop. It doesn't look like you've declared the object yet, so it can't dynamically add to a null object.
$scope.internalReps = {};
angular.forEach(internalRepList, function (rep) {
repName = rep.such;
$scope.internalReps[repName] = {};
$scope.internalReps[repName].such = repName;
//alert(repName);
});
var internalReps = {};
angular.forEach(internalRepList, function (rep) {
repName = rep.such;
internalReps[repName] = { such: "" };
internalReps[repName].such = repName;
//alert(internalReps[repName].such);
});
That worked. Thanks for the help!

Making a generic code of Angular JS by using Arrays

I'm trying to make a generic code to make it in a simple way for next level purpose. Please find the commented code which I've made. But, its not working.
var app = angular.module('myApp', []);
app.factory('mainFactory',function($http){
return {
getData: function() {
return $http.get("data.json");
}
};
});
app.controller('mainCtrl', function($scope,$http,mainFactory){
var data = mainFactory.getData();
if(angular.isDefined(data)) {
data.success(function(d,s){
// I want this commented out code for the four lines defined below.
/*var a = [{name:"imagesArray"},{name:"taskArray"},{name:"courseArray"},{name:"newsArray"}];
for(var i = 0; i < a.length; i++) {
$scope.a[i].name = d.a[i].name ? d.a[i].name : [];
}*/
// I dont want this number of lines.
$scope.imagesArray = d.imagesArray ? d.imagesArray : [];
$scope.taskArray = d.taskArray ? d.taskArray : [];
$scope.courseArray = d.courseArray ? d.courseArray : [];
$scope.newsArray = d.newsArray ? d.newsArray : [];
});
}
});
If it can be simplified further, please let me know
You can use this for better way to define scope property, edit your code like below:
data.success(function(d,s){
var keyCollection = ["imagesArray","taskArray","courseArray","newsArray"];
keyCollection.forEach(function(key){
$scope[key] = d[key];
});
});
or if your project are also using lodash(or underscore).You can simply do this(just further , don't import lodash or underscore just because this one, no need cost):
// outside, create advance function
var advancePick = _.partialRight(_.pick, "imagesArray", "taskArray", "courseArray", "newsArray");
data.success(function(d,s){
// just beauty like this
_.extend($scope, advancePick(d));
});
Change $scope.a[i].name = d.a[i].name ? d.a[i].name : []; to
$scope[a[i].name] = d[a[i].name] || [];
In Javascript, you can access properties two ways :
1)
item.property
2)
item["property"]
Thomas already gave you the right answer.
If you want to simplify it further, you can get rid of the definition of your "var a" array by making an object. Then you can enumerate each public property using :
for(var propertyName in yourObject) {
// propertyName is is the name of each property
// you can get the value using: yourObject[propertyName ]
}
Happy coding!
var a = ["imagesArray","taskArray","courseArray","newsArray"];
for(var i = 0; i < a.length; i++) {
$scope[a[i]] = d[a[i]] ? d[a[i]] : [];
}
with the name version
var a = [{name:"imagesArray"},{name:"taskArray"},{name:"courseArray"},{name:"newsArray"}];
for(var i = 0; i < a.length; i++) {
$scope[a[i].name] = d[a[i].name] ? d[a[i].name] : [];
}
A last solution and the shortest most of all!
angular.merge($scope, d);
EDIT : this will work only if d is properly initialized before.
Other simplifications not related to those 4 lines:
you don't need $http injected into your controller, and you don't
need to test the result of the call to getData(): it returns a
promise, take that as given.
Also use .then(...) rather than the deprecated .success(...).
You
might however want to add .catch(...) onto the promise to handle or
at least log errors, but if just to log errors you can put that inside .getData() and keep the controller short.
Here's how those changes might look:
var app = angular.module('myApp', []);
app.factory('mainFactory',function($http, $log){
return {
getData: function() {
return $http.get("data.json")
.catch(function (e) { $log.error(e); });
}
};
});
app.controller('mainCtrl', function($scope,mainFactory){
mainFactory.getData()
.then(function(d){
// choose one of the other answers for the code here...
var keyCollection = ["imagesArray","taskArray","courseArray","newsArray"];
keyCollection.forEach(function(key){
$scope[key] = d[key];
});
});
});

JavaScript Objects Error using dot notation

$(document.body).on("click",'.sub-unfollow', function(){
var unfollow_tag = {element:"",un:"",type:"",text:""};
var unfollow_tag.element = $(this).parents("li");
var unfollow_tag.un = $(this).parents("li").attr("data-un");
var unfollow_tag.type = $(this).parents("li").attr("data-type");
var unfollow_tag.text = $(this).parents("li").text();
alert(unfollow_tag.text);
});
Getting an error with this seemingly basic object setup. Any ideas?
You should remove var after once declaring unfollow_tag, it redeclares it instead of trying to access a property.
$(document).on("click",'.sub-unfollow', function(){
var unfollow_tag = {};
unfollow_tag.element = $(this).parents("li");
unfollow_tag.un = $(this).parents("li").attr("data-un");
unfollow_tag.type = $(this).parents("li").attr("data-type");
unfollow_tag.text = $(this).parents("li").text();
alert(unfollow_tag.text);
});

javascript TypeError: window.document.getElementById(...) is null

I use the following code to get links from a page but when I try to write it to an array I get the error message. I tested it with Firebug-Console.
function getElements() {
var mylinks = new Array();
for (var i=1;i<50;i++){
var linkID = "websiteLink" + i;
var element = window.document.getElementById(linkID).innerHTML;
mylinks[i-1] = element;
}
//alert(mylinks[0]);
}
getElements();
try
function getElements() {
var mylinks = new Array();
for (var i=1;i<50;i++){
var linkID = "websiteLink" + i;
var element = document.getElementById(linkID);
if(element !== null)mylinks.push(element.innerHTML);
}
//alert(mylinks[0]);
}
getElements();
you are trying to access the value property of the innerHTML property of a Dom node
I would suggest using jquery here to get a more failsafe/cross browser result.
Add 'websiteLink' as a class to all the links you want to grab.
var mylinks = [];
$('.websiteLink').each(function(idx,item){
mylinks.push($(item).html());
});
alert(mylinks);

Javascript / Chrome Extension

This is the code that I made that has worked but all of a sudden stopped working:
var waitEqua = 1 * 1 * 1000;
function getTC() {
$.get (
'http://www.roblox.com/marketplace/tradecurrency.aspx',
function parseData(data) {
var stuff = $(data).find('.CurrencyQuote');
var rowh = stuff.find('.TableRow');
var rate = rowh.find('.Rate');
var rateb = /(......)(.)(......)/(rate.text());
var spread = rowh.find('.Spread').text();
localStorage["Tix"] = rateb[1];
localStorage["Robux"] = rateb[3];
localStorage["Spread"] = spread;
spreadTehToast(spread);
}
);
}
My error is at var rateb = /(......)(.)(......)/(rate.text()); with the error Uncaught TypeError: object is not a function. I have not changed the code. It has just broke.
var rateb = /(......)(.)(......)/(rate.text());
is not valid JS to the best of my knowledge (the RegEx is not a function but an object as the error suggests, yet you're trying to use it as a function), it looks like a call to exec() has gone missing. Try this:
var rateb = /(......)(.)(......)/.exec(rate.text());

Categories