foreach Statements with a function - javascript

ok I am trying to answer a question and learning to code. regarding an array and using foreach statements the function must remain as this "function animalNames" must stay somewhere but apparently, I am doing something wrong because I get it returned as undefined. even through it produces the correct array back could someone look at it and let me know what i have done wrong.
attached is a picture of the code and array and question that i answered. this is how i wrote my function.
const displayNames = [];
zooAnimals.forEach(function animalNames(element){
var display = "name: " + element.animal_name + ", " + "scientific: " + element.scientific_name
displayNames.push(display);
})
console.log(displayNames);
again i get the correct array back and the data looks correct...but animalNames comes back as undefined...i cannot remove this portion i am to keep it there but i do not know what to do with it.

try this, it defines a function animalNames as separate function
const displayNames = [];
const zooAnimals = [
{animal_name:"Jackel",scientific_name:"Canine"}
]
function animalNames({animal_name, scientific_name}){
return `name: ${animal_name}, scientific: ${scientific_name}`
}
zooAnimals.forEach((element)=>{
displayNames.push(animalNames(element));
})
console.log(displayNames);

I believe you are following this challenge. In this case, make sure to read the instructions properly:
The zoos want to display both the scientific name and the animal name in front of the habitats.
Use animalNames to populate and return the displayNames array with only the animal name and scientific name of each animal.
displayNames will be an array of strings, and each string should follow this pattern: "name: {name}, scientific: {scientific name}"
So from the instructions you are expected to create a function animalNames() that creates an array named displayNames and returns this array from within your function animalNames(). The array displayNames contains strings of the sturcture name: animal_name, scientific: scientific_name.
// you could set zooAnimals as a required parameter in your function
// but as it is defined in the same file you can access it directly as well
function animalNames() {
const displayNames = [];
// you have to do the forEach on zooAnimals here
zooAnimals.forEach(animal => displayNames.push(`name: ${animal.animal_name}, scientific: ${animal.scientific_name}`))
// return an array
return displayNames;
}
The way you did it, the function animalsName() is an anonymous function that only exists within the zooAnimals.forEach() call. Therefore, it is undefined.

Related

Error preparing array in php to use in query in

I send the array with getJSON like this:
$.getJSON('valreceber1.php?arr'+ '&arr=' + arr, function (data6) {
});
Where the array is returned this way, when I do var_dump:
$id_utt1 = $_GET['arr'];
var_dump($id_utt1);
Data looks like this:
arr:
arr: 602,602,602,755,602,602,602
When I apply this line of code, I always get an error:
$in = str_repeat('?,', count($id_utt1) - 1) . '?';
How can I solve?
In your call to the PHP code, you are creating a blank element as you add the same variable in twice (arr)...
$.getJSON('valreceber1.php?arr'+ '&arr=' + arr, function (data6) {
});
This will mean that, as you can see there are two elements instead of just the one.
So firstly -
$.getJSON('valreceber1.php?arr=' + arr, function (data6) {
});
This is also giving you a string of comma separated numbers and not an array of values, so use something like explode() to split it into an array...
$id_utt1 = explode(',', $_GET['arr']);

can't iterate over map containing objects from custom class

I have a map that I created to store several instances of a custom class I wrote. If I do a simple console.log(myMapName), I see the details in the output. I see the six entries in my map, I see the key values I stored them under, and then for each entry, I can expand it and see the internals of that instance of my custom class, including the stored values for each attribute in that class definition.
But if I try to use for(let[key,value] of myMapName) to loop over the instances of my class stored as entries in my map and write the key and value of each one to the console using console.log, I see nothing. I can't even get it to at least log the key value for each entry. I would not be surprised if I was doing something wrong to cause it not to log the details of the value of each entry, but the fact that it also refuses to at least list the key value stumps me.
I should mention that I am able to loop over a small test map I created and get the key and value output in the log. Shown here below:
// test map definition
let myMap = new Map();
myMap.set('First',{name: 'John', age: '34'})
myMap.set('Second',{name: 'Mary', age: '24'})
// I can loop over this simple map
console.log(myMap)
for(let [key,value] of myMap){
console.log('key: ' + key)
console.log('value.name: ' + value.name)
console.log('value.age: ' + value.age)
}
// log output for above
// but using the same loop structure for my map doesn't work
for(let [key,value] of mgroups){
console.log('key: ' + key)
console.log('value: ' + value)
console.log('value.name: ' + value.name)
}
Edit: adding my class' code and a pic of its log output. the loop code is shown already above:
class MaterialGroup {
constructor(name){
this.name = name;
this.alias = name;
this.usemtl = "";
this.faces = [];
this.indices = [];
this.vertices = [];
}
setName(name){ this.name = name; }
getName(){ return this.name; }
setGroupIndices(){}
getGroupIndices(){}
setGroupVertices(){}
getGroupVertices(){}
}
module.exports = MaterialGroup
Sample of log output of console.log(mgroups):
Edit#2: below is the function where I use node.js' fs module's readline to to read in a file and populate the instances of my custom class (shown above) and then add each to the mgroups map. This is done and completed before the attempt to loop mentioned in the question but might be where the async issue I am seeing is introduced. This method gets called to read in the data and populate the mgroups map and then right after that another method is called to loop over it.
function readObjFile(objFilePath){
var objInput = fs.createReadStream(objFilePath);
var rl = require('readline').createInterface({
input: objInput,
terminal: false
});
...
let mgroup = new MaterialGroup("NotSet");
rl.on('line', function(line){
var pieces = line.split(" ");
...
// section of function that works with MaterialGroup class that
// gets added to my mgroups map using .set calls
if(pieces[0] == "g"){
var mpieces = pieces[1].split("_");
if(processing == "mgroups"){
mgroups.set(mgroup.name, mgroup);
mgroup = new MaterialGroup(mpieces[mpieces.length - 1]);
} else {
processing = "mgroups";
mgroup = new MaterialGroup(mpieces[mpieces.length - 1]);
}
}
if(pieces[0] == "usemtl"){
mgroup.usemtl = pieces[1];
}
// this is new f block for material group faces
if(pieces[0] == "f"){
mgroup.faces.push([pieces[1]-1,pieces[2]-1,pieces[3]-1]);
mgroup.indices.push(pieces[1]-1);
mgroup.indices.push(pieces[2]-1);
mgroup.indices.push(pieces[3]-1);
mgroup.vertices.push(vertices[pieces[1]]);
mgroup.vertices.push(vertices[pieces[2]]);
mgroup.vertices.push(vertices[pieces[3]]);
indices.push(pieces[1]-1);
indices.push(pieces[2]-1);
indices.push(pieces[3]-1);
}
if(pieces[0] == "eof"){
mgroups.set(mgroup.name, mgroup);
}
}).on('close', () => {
...
setMgroupsMap(mgroups);
});
}
I can do a simple console.log(mgroups) and see all of the entries and their details but I can't loop over them one by one.
One thing that caught my attention is that even in the log where I can see the six entries and their details, it shows Map(0) at the top of that log entry. This makes no sense to me since in the details below the six entries I see the size entry for the map and there it shows a value of 6.
Does anyone know of a detail has to be addressed when attempting to loop over the entries of a map that are instances of a custom class definition? I think this is the root cause since the only other difference I notice between my output and a test output I did of a simple make using standard object entries like {'name':'John', 'age':'34'} (aside from the fact that this test map showed the correct size of Map(2) at the top of its log output) was that for my map it shows {"KeyValue" => MyCustomClassName} and the simple test map just shows {"KeyValue" => Object}.
I'm sure I'll get a lot of "this has been asked" quick replies, but I have looked at this from many angles and tried a lot of different ways to loop it and have gotten nowhere, and I have tried looking at many other posted questions but they did not help. So, thanks to anyone who takes the time to provide a helpful reply.
class Person {
constructor(name, age) {
this.name = name
this.age = age
}
}
let mgroups = new Map()
mgroups.set('First', new Person('John', '34'))
mgroups.set('Second', new Person('Mary', '24'))
for (let [ key, value ] of mgroups) {
console.log('key: ' + key)
console.log('value: ' + value)
console.log('value.name: ' + value.name)
console.log('value.age: ' + value.age)
}

How to replace ' / ' with '-' inside ObservableArray ? Knockout js

Well i am trying to pass an observable array via ajax call to my controller but i get every value there except date . i get something like '01-01-01' etc .
I found the issue but unable to fix that as i dont know how to replace / with - .
My ObservableArray have around 10 list items each list item holds a many properties out of those startDate holds the date like ("23/10/2014") . i just need something like ("23-10-2014") .
Tought of posting my function's and more i hope thats not required in this case i believe .
Let me explain with bit of code and sample data :
function myarray()
{
var self=this;
self.startDate=ko.observable("");
self.name=ko.observable("");
self.place=ko.observable("");
}
MyObservableArray :
self.Main= ko.observableArray();
In between i do some stuff to load Data into self.Main and i am sending self.Main to controller having data like below :
self.Main[0] holds :
startDate() -->gives you "23/10/2014" //individual observables inside onservable array
name() --> "jhon"
place()--> "croatia"
Likely
self.Main[9] holds :
startDate() --> "29/05/2012"
name() --> "pop"
place()--> "usa"
I am trying like i want to alter the self.Main() and replace the startDate and use the same self.Main to send to my controller . Once after replacing in self.Main when i check date the / should be replaced with - .
Possible solution : i can use a different observable array and push all the VM's of Main into it but i am trying to do on self.Main without using other .
If someone can show some light it is much appreciated .
What I got that you are facing problem in escaping / in replace.
Try this
"(23/10/2014)".replace(/\//g,"-") //returns "(23-10-2014)"
I tried something for you using simple JS
var arr = [{date:"(23/10/2014)"},{date:"(23/10/2014)"},{date:"(23/10/2014)"},{date:"(23/10/2014)"}];
arr.forEach(function(obj){obj.date = obj.date.replace(/\//g,"-")});
console.log(arr) //will print date field as "(23-10-2014)" for all objects.
One solution would be to add a computed value that returns the array with the right values.
self.Main = ko.observableArray([...values here...]);
self.MainComputed = ko.computed(function() {
var computedArray = [];
self.Main().forEach(function(item) {
var newItem = myarray(); //Create a new item.
newItem.name(item.name());
newItem.place(item.place());
newItem.startDate(item.startDate().replace(/\//g,"-"));
computedArray.push(newItem);
});
return computedArray;
});
Then use the computed value in the places where you need the values with -.
I can think of two other ways to solve your issue, when taken into account that you want to use self.Main:
Replace the / with - before setting startDate on your item.
Change startDate to a computed value while storing the original value in another variable.
The first solution should be pretty straight forward (provided that it is a valid solution).
The second solution would look something like this:
function myarray()
{
var self=this;
self.originalStartDate = ko.observable("");
self.name = ko.observable("");
self.place = ko.observable("");
self.startDate = ko.computed(function() {
if(self.originalStartDate()) {
//We can only replace if the value is set.
return self.originalStartDate().replace(/\//g,"-");
}
else {
//If replace was not possible, we return the value as is.
return self.originalStartDate();
}
});
}
Now when you set the values you do something like:
var item = myarray();
item.originalStartDate = "01/01/2014";
Then when you get the value of startDate you would get "01-01-2014".
I haven't used Knockout.js but you can do this with a Javascript replace:
var str = [your array value] ;
var res = str.replace("/", "-");
For more information:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replace

Fill observable-fields-object by same fields-names object

I have object that all of its fields are observable (knockout.observable).
I have other regular object too, that its fields have the same names like the first-object-fields.
I want to insert into each field of the first object, the value of the match-field at the second object.
For example:
var first = {
a:ko.observable(),
b:ko.observable()
};
var second= {
a:'my'
b:'fields';
};
I want the first object to look like:
first = {
a:ko.observable('my'),
b:ko.observable('fields')
};
Yes, of course, I can do it by 'each' loop.
But, my question is:
Is there any build-in function that does it?
You can use the ko.mapping plugin:
var results = ko.mapping.fromJS(second, first);
See Documentation

Javascript [Object object] error in for loop while appending string

I am a novice trying to deserialize my result from an onSuccess function as :
"onResultHttpService": function (result, properties) {
var json_str = Sys.Serialization.JavaScriptSerializer.deserialize(result);
var data = [];
var categoryField = properties.PodAttributes.categoryField;
var valueField = properties.PodAttributes.valueField;
for (var i in json_str) {
var serie = new Array(json_str[i] + '.' + categoryField, json_str[i] + '.' + valueField);
data.push(serie);
}
The JSON in result looks like this:
[
{
"Text": "INDIRECT GOODS AND SERVICES",
"Spend": 577946097.51
},
{
"Text": "LOGISTICS",
"Spend": 242563225.05
}
]
As you can see i am appending the string in for loop..The reason i am doing is because the property names keep on changing therefore i cannot just write it as
var serie = new Array(json_str[i].propName, json_str[i].propValue);
I need to pass the data (array type) to bind a highchart columnchart. But the when i check the var serie it shows as
serie[0] = [object Object].Text
serie[1] = [object Object].Spend
Why do i not get the actual content getting populated inside the array?
You're getting that because json_str[i] is an object, and that's what happens when you coerce an object into a string (unless the object implements toString in a useful way, which this one clearly doesn't). You haven't shown the JSON you're deserializing...
Now that you've posted the JSON, we can see that it's an array containing two objects, each of which has a Text and Spend property. So in your loop, json_str[i].Text will refer to the Text property. If you want to retrieve that property using the name in categoryField, you can do that via json_str[i][categoryField].
I don't know what you want to end up with in serie, but if you want it to be a two-slot array where the first contains the value of the category field and the second contains the value of the spend field, then
var serie = [json_str[i][categoryField], json_str[i][valueField]];
(There's almost never a reason to use new Array, just use array literals — [...] — instead.)

Categories

Resources