How can I access the scope inside foreach to grab the variable value ?
var fruitCollection = ['Grape','Orange','Banana'];
// give me a .txt file with the recipe for each fruit
var fruitsNeeded = function(){
fruitCollection.forEach(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
return fruitRecipe;
});
}
fruitsNeeded(); // undefined
EDIT Expected output:
// grape.txt
// orange.txt
// banana.txt
You cannot return the value from forEach function
forEach() executes the callback function once for each array element; unlike map() or reduce() it always returns the value undefined and is not chainable.
You could use map function for it
var fruitCollection = ['Grape','Orange','Banana'];
var fruitsNeeded = function(){
return fruitCollection.map(function(fruit) {
return fruit.toLowerCase() + '.txt';
});
}
ES6 snippet:
var fruitCollection = ['Grape','Orange','Banana'];
var fruitsNeeded = () => fruitCollection.map(f => f.toLowerCase() + '.txt');
document.write(JSON.stringify(fruitsNeeded()));
Another option is to build an array and return the whole array:
var fruitCollection = ['Grape','Orange','Banana'];
// give me a .txt file with the recipe for each fruit
var fruitsNeeded = function(){
var fruitRecipeList = [];
fruitCollection.forEach(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
fruitRecipeList.push(fruitRecipe);
});
return fruitRecipeList;
}
fruitsNeeded();
forEach has no return value; it is simply a way to execute over an array. You probably want map:
var fruits = fruitCollection.map(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
return fruitRecipe;
});
// fruits = ['grape.txt','orange.txt','banana.txt']
Rather then returning a value from the forEach, you can add them to another global scope variable.
Like this:
var fruitCollection = ['Grape','Orange','Banana'];
var fruitFiles = [] ;
// give me a .txt file with the recipe for each fruit
var fruitsNeeded = function(){
fruitCollection.forEach(function(fruit) {
var fruitRecipe = fruit.toLowerCase() + '.txt';
fruitFiles.push(fruitRecipe) ;
});
return fruitFiles ;
}
fruitsNeeded(); // ["grape.txt", "orange.txt", "banana.txt"]
I hope this helps,Jacob
Related
I have the below code which is called onclick, and want to be able to show a second image after a few seconds, depending on which one is chosen from the array - so for example if 1.png is shown, then I want to show 1s.png, 2.png then show 2s.png etc
function displayImage () {
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
}
How do I determine which image has been chosen from the array to then use in another function please ?
You're gonna need a global var for knowing that function is running for the first time or not.
var alreadyRandom = false;
function displayImage()
{
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
if(alreadyRandom)
{
// If the random for first time is done
var rnd_no = img_name.indexOf(document.getElementById("imgHolder").getAttribute('src'));
if(rnd_no === img_name.length-1)
{
// If the current image is the last one in array,
// go back to the first one
rnd_no = 0;
}
else
{
// Choose the next image in array
rnd_no++;
}
document.getElementById("imgHolder").src = img_name[rnd_no];
}
else
{
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
alreadyRandom = true; // Tell the function not to random again
}
return img_name[rnd_no];
}
Demo: http://jsbin.com/kanejugahi/edit?html,js,console,output
Moreover, making the array global would make your function more efficient.
Hope this helps,
I think it's important you understand how Functions work in JavaScript and how scope works.
What you need to do is you need to expose that information so that both functions have access. You have the array of images defined and you have already determined the random number so just make them available by declaring them outside of the function so now these variables are available. Defining variables in the global scope is generally bad practice but this is simply for teaching.
var selectedImage; // defined outside so it is available for other functions
function displayImage() {
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var rnd_no = Math.floor(img_name.length * Math.random());
selectedImage = img_name[rnd_no];
document.getElementById("imgHolder").src = selectedImage;
}
function anotherFunction() {
console.log(selectedImage);
}
As far as I understand the question, you can use a return and make the image array global.
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var img_class = '';
//this function will return the index of the image in array
function displayImage () {
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
return rnd_no;
}
var nextimage;
function showImages(){
//your logic to show the next image here
nextimage = (displayImage ()+1)%img_name.length;
var myVar = setInterval(function(){
if(img_class==''){
document.getElementById("imgHolder").src = img_name[nextimage];
img_class = 's';
}else{
var img_arr = img_name[nextimage].split(".");
if(img_arr.length===2){
document.getElementById("imgHolder").src = img_arr[0]+"s."+img_arr[1];
}
img_class = '';
nextimage = (nextimage+1)%img_name.length;
}
}, 1000);
}
var img_name = new Array("images/1.png", "images/2.png", "images/3.png");
var img_class = '';
//this function will return the index of the image in array
function displayImage () {
var l = img_name.length;
var rnd_no = Math.floor(l*Math.random());
document.getElementById("imgHolder").src = img_name[rnd_no];
return rnd_no;
}
var nextimage;
function showImages(){
//your logic to show the next image here
nextimage = (displayImage ()+1)%img_name.length;
var myVar = setInterval(function(){
if(img_class==''){
document.getElementById("imgHolder").innerHTML = img_name[nextimage];
img_class = 's';
}else{
var img_arr = img_name[nextimage].split(".");
if(img_arr.length===2){
document.getElementById("imgHolder").innerHTML = img_arr[0]+"s."+img_arr[1];
}
img_class = '';
nextimage = (nextimage+1)%img_name.length;
}
}, 1000);
}
showImages();
<div id="imgHolder"></div>
Mayve something like this?
var images = ["images/1.png", "images/2.png", "images/3.png"];
function displayImage () {
var dom = document.getElementById("imgHolder");
if ( images.indexOf(dom.src) >=0 ) {
dom.src = dom.src.replace(".png", "s.png"); // Seems like a stupid way to do this
return;
}
var l = images.length;
dom.src = images[Math.floor(l*Math.random())];
}
for (...) {
files.push(files[i]);
li_out.push({name : fileName, list_files : files});
}
How to get the Array of list_files by name?
var list_files_of_file3 = li_out[name == "file3" (?????)].list_files;
Array#find can be used in this case.
var list_files_of_file3 = li_out.find(o => o.name === "file3").list_files;
// Variable names changed for DEMO purpose
var files = [];
for (var i = 0; i < 10; i++) {
files.push({
name: 'fileName ' + i,
list_files: 'something ' + i
});
}
var res = files.find(o => o.name === 'fileName 3').list_files;
console.log(res);
How to get the Array of list_files by name?
using filter, try
var result = li_out.filter(function(item){ return item.name == "file3" });
Is it also possible to just return a property of the matching items
instead of the whole object? (below comment #MajidFouladpour)
Once you have got the result
var propertyNames = result.map(function(obj){ return obj.propertName; })
I faced the following functions (or method I don't what is right name of the ):
function getRowArray($scope, object, i){
i = i + 1;
var item = {};
var data = [];
var id = -1;
if ($scope.selectedType !== undefined) {
id = $scope.selectedType.id;
}
var rating = getRating($scope, object, id);
item['name'] = $scope.objectInfo[object]['name'];
item['objectId'] = rating.objectId;
item['hideRating'] = parseInt($scope.objectInfo[object].hideControls) & 1;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
item['ratingId'] = rating.id;
for (var i in $scope.objectInfo[object].childs) {
if ($scope.objectInfo[object].childs[i] == object){
continue;
}
data.push(getRowArray($scope, $scope.objectInfo[object].childs[i], i));
}
item['data'] = data;
return item;
}
and
function getTypeRow($scope, oobject, otype){
var item = {};
var data = [];
var rating = getRating($scope, oobject.id, otype.id);
item['name'] = otype.name;
item['objectId'] = rating.objectId;
item['typeId'] = rating.typeId;
item['ratingId'] = rating.id;
item['addInfo'] = rating.addInfo;
item['rating'] = rating.value;
// item['hideRating'] = parseInt($scope.objectInfo[object].hideControls);
return item;
}
I want to use the hideRating item from the first one in the second, I tried and added the commented line but I got an error it says the object is undifined, is it wrong like that or am I missing something ? thanks in advance
object is undefined because it wasn't initialized; it's not specified in the parameter list for the function getTypeRow. The oobject in the parameter list should be corrected to object:
// Correct 'oobject' to 'object'
function getTypeRow($scope, object, otype){
var item = {};
var data = [];
// Correct 'oobject' to 'object'
var rating = getRating($scope, oobject.id, otype.id);
...
}
I am trying to pass product into the find() function that contains a .toArray() anonymous function containing both error and array. Unfortunately this entire find() function runs within an iteration and only the first value goes in. How do I pass product to the callbacks?
var find = function(product,callbacks){
foos.find({
"foo": product.bars,
}).toArray(function (error, array) {
if(error){
callbacks.error(product,error);
} else if (array.length == 0) {
callbacks.none(product);
} else {
callbacks.exists(product);
}
});
}
Before this function i was processing products with forEach() then had this run in a callback within that. This was big trouble. Processed products with a regular for and now it works.
Old code
var products = function(data,callback){
products.forEach(function(product){
insert.product_id = product.id;
var variants = product.variants;
variants.forEach(function(variant){
insert.sku = variant.sku;
insert.variant_id = variant.id;
return callback(insert);
});
});
}
New code
var products = function(data){
var insert = [];
var products = data.products;
for(var pKey in products){
var product = products[pKey];
var variants = product.variants;
var set = {}
set.product_id = product.id;
for(var vKey in variants){
var variant = variants[vKey];
set.sku = variant.sku;
set.variant_id = variant.id;
insert.push(set);
}
}
return insert;
}
may be you can help me. How can I create global object and function that return object values by id?
Example:
var chat = {
data : {
friends: {}
}
}
....
/*
JSON DATA RETURNED:
{"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
*/
onSuccess: function(f){
chat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends.push(f.users[i])
}
}
How can I create a new function (It will return values by friend_id)?
get_data_by_id: function (what, friend_id) {
/*obj.what = getfrom_globalobject(chat.data.friends???)*/
}
Example of use:
var friend_name = get_data_by_id(name, 62);
var friend_username = get_data_by_id(username, 62);
var friend_avatar = get_data_by_id(thumb, 62);
Try:
get_data_by_id: function (what, friend_id) {
return chat.data.friends[friend_id][what];
}
... but use it like:
var friend_name = get_data_by_id('name', 62);
...and set up the mapping with:
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i];
}
You cannot .push() to an object. Objects are key => value mappings, so you need to use char.data.friends[somekey] = f.users[i];
If you really just want a list with numeric keys, make x5fastchat.data.friends an array: x5fastchat.data.friends = [];
However, since you want to be able to access the elements by friend_id, do the following:
onSuccess: function(f){
x5fastchat.data.friends = {};
for(var i=0; i< f.users.length;i++){
chat.data.friends[f.users[i].friend_id] = f.users[i]
}
}
get_data_by_id: function (what, friend_id) {
obj[what] = chat.data.friends[friend_id][what];
}
Note the obj[what] instead of your original obj.what: When writing obj.what, what is handled like a string, so it's equal to obj['what'] - but since it's a function argument you want obj[what].
Take a look at the following code. You can simply copy paste it into an HTML file and open it. click "go" and you should see the result. let me know if I did not understand you correctly. :
<script>
myObj = { "field1" : { "key1a" : "value1a" }, "field2" : "value2" }
function go()
{
findField(myObj, ["field2"])
findField(myObj, ["field1","key1a"])
}
function findField( obj, fields)
{
var myVal = obj;
for ( var i in fields )
{
myVal = myVal[fields[i]]
}
alert("your value is [" + myVal + "]");
}
</script>
<button onclick="go()">Go</button>
I would recommend using the friend objects rather than getting them by id and name.
DATA = {"users": [{"friend_id":"62","name":"name","username":"admin","thumb":"images/avatar/thumb_7d41870512afee28d91.jpg","status":"HI4","isonline":""},{"friend_id":"66","name":"Another name","username":"regi","thumb":"images/avatar/thumb_d3fcc14e41c3a77aa712ae54.jpg","status":"Всем привет!","isonline":"avtbsl0a6dcelkq2bd578u1qt6"},{"friend_id":"2679","name":"My name","username":"Another","thumb":"images/avatar/thumb_41effb41eb1f969230.jpg","status":"","isonline":""}]}
// simple data store definition
Store = {items:{}};
NewStore = function(items){
var store = Object.create(Store);
store.items = items || {};
return store
};
Store.put = function(id, item){this.items[id] = item;};
Store.get = function(id){ return this.items[id]; };
Store.remove = function(id){ delete this.items[id]; };
Store.clear = function(){ this.items = {}; };
// example
var chat = {
data : {
friends : NewStore()
}
}
// after data loaded
chat.data.friends.clear();
for( var i = 0; i < DATA.users.length; i += 1 ){
var user = DATA.users[i];
chat.data.friends.put( user.friend_id, user );
}
getFriend = function(id){ return chat.data.friends.get( id ); }
var friend = getFriend(66);
console.log(friend.name);
console.log(friend.username);
console.log(friend.thumb);