Here is my object:
$scope.info = [];
$scope.info = [{"name":"kanye","size":"","folder":"Folder"},{"name":"west","size":"","folder":"Folder"}]
$scope.infoObj = $scope.info.name;
console.log($scope.infoObj);
This return me Undefined. The response should be like this:
[{"name":kanye},{"name":west}]
But how to access the specific properties from a multiple object using angularJS or jquery/js?
This should solve the problem:
$scope.infoObj = $scope.info.map(function(obj){
var x = {};
x['name'] = obj['name'];
return x;
})
for ES6, it can be simplified to:
$scope.infoObj = $scope.info.map(x => ({name:x['name']}))
You can actually do a little bit of refactoring to make your code a little cleaner and more readable. Instead of setting your info value twice, set it once, and add the objects in each line after.
Like this:
$scope.info = [];
$scope.info.push({
"name":"kanye",
"size":"",
"folder":"Folder"
});
$scope.info.push({
"name":"west",
"size":"",
"folder":"Folder"
});
See how clean that is? Now it should be fairly obvious that info is an Array of objects, so doing $scope.info.name won't work. What I would recommend is creating a lookup function that can help grab a list based on the key you provide it.
Something like this:
function lookup(key) {
var result = [];
for (var i = 0; i < $scope.info.length; i++) {
var object = {};
object[key] = $scope.info[i][key];
result.push(object);
}
return result;
}
And then call it like this:
$scope.infoObj = lookup('name');
console.log($scope.infoObj);
Related
I have following javascript variable:
this.Edges = {};
Then I did
this.Edges[path] = {edgeDst};
So Edges variable at this point is somehing like
Edges['232kb32i23'] = { edgeDst: 'AND_m_5' }
after that I when I did
this.Edges[path] = {edgeSrc};
It overwrote the value I had added with edgeDst.
At this point Edges is like following:
Edges['232kb32i23'] = { edgeSrc: 'B_m_5' }
But I want to produce something like:
Edges['232kb32i23'] = { edgeDst: 'AND_m_5', edgeSrc: 'B_m_5' }
Here I can't added edgeSrc and edgeDst simulataneously.
How will I achieve this?
You can use the following:
var Edges = {}; // these are just so that you can run the snippet
var path = '232kb32i23';
Edges[path] = {}; // set Edges[path] to a new object
Edges[path].edgeDst = 'AND_m_5'; // set the edgeDst property on Edges[path]
Edges[path].edgeSrc = 'B_m_5'; // set the edgeSrc property on Edges[path]
console.log(Edges); // run the snippet to see the result
console.log(Edges['232kb32i23']);
You will have to modify the code to use this for your application, but I tried to make as succinct an example as possible.
If you want to use the new ES6 syntactic sugar. It looks like you can do something like this:
this.Edges = {};
var path = 'the_path',
edgeDst = 'edgeDst',
edgeSrc = 'edgeSrc';
this.Edges[path] = { edgeDst, edgeSrc };
console.log(this.Edges) => {edgeDs:"AND_m_5",edgeSrc:"edgeSrc"}
Here is a link to a functioning example: https://jsfiddle.net/xwf3wadr/
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];
});
});
});
Here is the code:
http://jsfiddle.net/GKBfL/
I am trying to get collection.prototype.add to return a reference such that the final alert will display testing, testing, 123, testing. Is there a way to accomplish what I'm trying to do here?
HTML:
<span id="spantest">testing, testing, 123, testing</span>
JavaScript:
var collection = function () {
this.items = {};
}
collection.prototype.add = function(sElmtId) {
this.items[sElmtId] = {};
return this.items[sElmtId];
}
collection.prototype.bind = function() {
for (var sElmtId in this.items) {
this.items[sElmtId] = document.getElementById(sElmtId);
}
}
var col = new collection();
var obj = {};
obj = col.add('spantest');
col.bind();
alert(obj.innerHTML);
You problem is this line:
this.items[sElmtId] = document.getElementById(sElmtId);
This overwrites the object currently assigned to this.items[sElmtId] with the DOM node. Instead, you should assign the node to a property of that object:
this.items[sElmtId].node = document.getElementById(sElmtId);
That way, obj.node will always refer to the current node:
alert(obj.node.innerHTML);
DEMO
Side note: The problem with your fiddle is also that you execute the code when the DOM is not built yet (no wrap (head)), so it cannot find #spantest. You have to run the code once the DOM is ready, either no wrap (body), onDomRead or onLoad.
Creating a reference like you need is impossible in JavaScript. The closest thing you can get is either a nested or closed object, or just copying it over, like so:
var collection = function() {
this.items = {};
};
collection.prototype.add = function(sElmtId) {
return this.items[sElmtId] = {};
};
collection.prototype.bind = function() {
for(var sElmtId in this.items) {
var element = document.getElementById(sElmtId);
for(var x in element) {
this.items[sElmtId][x] = element[x];
}
}
};
var col = new collection();
var obj = {};
obj = col.add('spantest');
col.bind();
alert(obj.innerHTML);
But it won't be truly "bound". You'll have to use nested objects if you need that kind of functionality, and it will probably defeat the point of your syntactic sugar.
http://jsfiddle.net/GKBfL/7/
I'm trying to translate a PHP class into JavaScript. The only thing I'm having trouble with is getting an item out of an array variable. I've created a simple jsfiddle here. I cannot figure out why it won't work.
(EDIT: I updated this code to better reflect what I'm doing. Sorry for the previous mistake.)
function tattooEightBall() {
this.subjects = ['a bear', 'a tiger', 'a sailor'];
this.prediction = make_prediction();
var that = this;
function array_random_pick(somearray) {
//return array[array_rand(array)];
var length = somearray.length;
var random = somearray[Math.floor(Math.random()*somearray.length)];
return random;
}
function make_prediction() {
var prediction = array_random_pick(this.subjects);
return prediction;
}
}
var test = tattooEightBall();
document.write(test.prediction);
Works fine here, you are simple not calling
classname();
After you define the function.
Update
When you make a call to *make_prediction* , this will not be in scope. You are right on the money creating a that variable, use it on *make_prediction* :
var that = this;
this.prediction = make_prediction();
function make_prediction() {
var prediction = ''; //initialize it
prediction = prediction + array_random_pick(that.subjects);
return prediction;
}
You can see a working version here: http://jsfiddle.net/zKcpC/
This is actually pretty complex and I believe someone with more experience in Javascript may be able to clarify the situation.
Edit2: Douglas Crockfords explains it with these words:
By convention, we make a private that variable. This is used to make
the object available to the private methods. This is a workaround for
an error in the ECMAScript Language Specification which causes this to
be set incorrectly for inner functions.
To see the complete article head to: http://javascript.crockford.com/private.html
You never call classname. Seems to be working fine.
Works for me:
(function classname() {
this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";
function pickone(somearray) {
var length = somearray.length;
var random = somearray[Math.floor(Math.random()*length)];
return random;
}
var random_item = pickone(this.list);
document.write(random_item);
}());
Were you actually calling the classname function? Note I wrapped your code block in:
([your_code]());
I'm not sure what you're trying to accomplish exactly with the class structure you were using so I made some guesses, but this code works by creating a classname object that has instance data and a pickone method:
function classname() {
this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";
this.pickone = function() {
var length = this.list.length;
var random = this.list[Math.floor(Math.random()*length)];
return random;
}
}
var cls = new classname();
var random = cls.pickone();
You can play with it interactively here: http://jsfiddle.net/jfriend00/ReL2h/.
It's working fine for me: http://jsfiddle.net/YznSE/6/ You just didn't call classname(). If you don't call it, nothing will happen ;)
Make it into a self-executing function like this:
(function classname() {
this.list = [];
this.list[0] = "tiger";
this.list[1] = "lion";
this.list[2] = "bear";
function pickone(somearray) {
var length = somearray.length; //<---WHY ISN'T THIS DEFINED??
var random = somearray[Math.floor(Math.random() * length)];
return random;
}
var random_item = pickone(this.list);
document.write(random_item);
})();
var test = tattooEightBall();
document.write(test.prediction);
Should be:
var test = new tattooEightBall(); //forgot new keyword to create object
document.write(test.prediction()); // forgot parens to fire method
and:
this.prediction = make_prediction();
Should be:
this.prediction = make_prediction;
I have a variable with a value, let's say
var myVarMAX = 5;
In HTML I have an element with id="myVar".
I combine the id with the string MAX (creating a string myVarMAX). My question is how can I use this string to access a variable with the same name?
You COULD use eval, but if you have the var in the window scope, this is better
var myVarMAX = 5;
var id="MAX"; // likely not in a var
alert(window["myVar"+id]); // alerts 5
However Don't pollute the global scope!
A better solution is something like what is suggested in the link I posted
var myVars = {
"myVarMin":1,
"myVarMax":5,
"otherVarXX":"fred"
} // notice no comma after the last var
then you have
alert(myVars["myVar"+id]);
Since this post is referred to often, I would like to add a use case.
It is probably often a PHP programmer who gives Javascript/Nodejs a try, who runs into this problem.
// my variables in PHP
$dogs = [...]; //dog values
$cats = [...]; //cat values
$sheep = [...]; //sheep values
Let's say I want to save them each in their own file (dogs.json, cats.json, sheep.json), not all at the same time, without creating functions like savedogs, savecats, savesheep. An example command would be save('dogs')
In PHP it works like this:
function save($animal) {
if(!$animal) return false;
file_put_contents($animal.'.json', json_encode($$animal));
return true;
}
In Nodejs/Javascript it could be done like this
// my variables in NodeJS/Javascript
let dogs = [...]; //dog values
let cats = [...]; //cat values
let sheep = [...]; //sheep values
function save(animal) {
if (!animal) return false;
let animalType = {};
animalType.dogs = dogs;
animalType.cats = cats;
animalType.sheep = sheep;
fs.writeFile(animal + '.json', JSON.stringify(animalType[animal]), function (err){
if (err) return false;
});
return true;
}