Array with repeating structure - javascript

I am creating a script that would show the keys of my array, in the first attempt worked perfectly, but when I added but a while block, he did not execute and returned this error:
classificacao-v2.js:128 Uncaught TypeError: Cannot read property 'Period' of undefined
at classificacao-v2.js:128
Realizing that my problem was in the variable 'n' that appeared as undefined, so I created other variables with different names for each structure.
I wonder if it is possible to rewrite it more efficiently without having to repeat each block.
let GoldemStates = [{Period: ' 1°',Points:'300'},
{Period: ' 2°',Points:'250'},
{Period: ' 3°', Points:'155'}]
let Chicago = [{Period: ' 1°',Points:'100'},
{Period: ' 2°',Points:'420'},
{Period: ' 3°', Points:'350'}]
let Broklyn = [{Period: ' 1°',Points:'300'},
{Period: ' 2°',Points:'250'},
{Period: ' 3°', Points:'155'}]
// Show the Teams
icons('','Match Results ','div_titulo')
let n = 0
icons('golden','Golden States', 'destaque_golden') //Team Title (Symbol, Team Name, CSS)
//Goldem States Statistics
do {
icons('clock',GoldemStates[n].Period + ' Period | ' + 'Points ' + GoldemStates[n].Points ,'texto') // // Show period and points
n ++
} while (n < GoldemStates.length);
let d = 0 // <-------- CHANGE WHICH WOULD NEED
//Chicago Bulls Statistics
icones('bulls','Chicago Bulls', 'destaque_bulls')//Team Title (Symbol, Team Name, CSS)
do {
icons('clock',Chicago[d].Period + ' Period | ' + 'Points ' + Chicago[d].Points ,'texto')// Show period and points
d ++
} while (d < Chicago.length);
Console Output

I think your code could be simpler, shorter and easier to read if you leave the iteration to array built in methods. That way you will remove the need to use an iteration variable and access each item:
GoldemStates.forEach(
item => icons('clock',item.Period + ' Period | ' + 'Points ' + item.Points ,'texto')
)
But we can do it eve better. Since all the teams render exactly the same, we can build a function that renders one single item and then let the methods specialized on iteration do their work. That way your code only takes care of rendering and the built-in methods takes care of iterating, separation of conerns:
const renderTeam = team => icons('clock',team.Period + ' Period | ' + 'Points ' + team.Points ,'texto')
// Render part
icons('golden','Golden States', 'destaque_golden') //Team Title (Symbol, Team Name, CSS)
GoldemStates.forEach(renderTeam)
icons('bulls','Chicago Bulls', 'destaque_bulls')//Team Title (Symbol, Team Name, CSS)
Chicago.forEach(renderTeam)

Related

I want to re-generate part of a random generated paragraph created from arrays

I am not entirely sure what to even search to find a solution here, but essentially I have a random text generator that creates a writing prompt from a series of arrays. The behaviour I want to add to it is the ability to "reroll" any of the individual random elements by clicking on them. Here's what the current function looks like that gets returned when the button is clicked.
function art_prompt() {
return (
'<p>' + 'The main character is a ' + get_three_random_words(personality) + ' ' + get_random_word(gender) +
' who ' + get_random_word(frequency) + ' ' + get_random_word(flaws) + ' and ' + get_random_word(frequency) +
' ' + get_random_word(flaws) + '. The character is paired with ' + get_random_word(atmospheres) +
' atmosphere, set ' + get_random_word(places) + ' during ' + get_random_word(time) + '.<br><br>' +
'The scene portrays ' + get_random_word(portrayals) + '.<br><br>' + '<strong>Bonus restriction:</strong> ' +
get_random_word(bonus_restrictions) + '.' + '</p>'
);
}
So essentially, each of the get_random_word(array) functions I want to be a clickable element that generates a new random string from the same array. I have tried something where each one has a button concatenated around it and create a separate function for each array that is being brought in, but I want a more elegant solution if one exists.
Also I realize it's a bit janky of an implementation, but it's all I knew how to do when I started on it.
So I seem to have figured out a working solution. Just wrapped each object in a button, like this:
'<p>' + 'The main character is a ' + '<button onclick="rollPersonality1()" class="reroll personality1">' + personality[rand1] + '</button>, '
Using the buttons is a bit janky but it seemed to do the trick in this instance. I ran into another issue where I was trying to run the onclick function the same way I did for a static button, but it didn't work because the selector outside the function was no good. So the function for the above looks something like this.
var rollPersonality1 = () => {
var PersonalityElement = document.querySelector('.personality1');
PersonalityElement.textContent = randomPersonality();
}
I doubt this will help anybody else, but if it does that's awesome! If anyone has a more elegant way of doing this, I am not super happy with the messiness of what I came up with. So lay it on me!

Why is the following way to assign a value to a JSON array not working?

I have this code:
compareList[productName] = productID + ',' + productHref;
console.log(productName + ' ' + productID + ' ' + productHref + ' ' + compareList.length);
Which logs into this (I have removed the link):
Acer Iconia B1-790 [NT.LDFEE.002] 112576 link removed for confidentiality 0
As you can see, all three variables are valid strings, but the json object still fails to assign (compareList.length logs as 0). I've been thinking and thinking but I simply can't figure it out. Any help is appreciated.
Maybe this version of adding and checking array length can be useful to you?
var compareList=[]
var productName = {productID:'saban',productHref:'http://saulic.com'};
compareList.push(productName);
console.log(compareList.length);

Lodash Operation sometimes fails to complete in Promise

I'm building a trading bot and I have this code which takes an array of arrays of 5 (API allows 5 price requests at a time). For each of these currencies, this api does an API call and retrieves results with a promise. In the promise I forEach through each currency returned, calculate the average of the prices and then save it to MongoDB.
Market.prototype.fetchPrices = function(currencyPairs){
var self = this
let currencyPairGroups = chunkBy5(currencyPairs)
_.forEach(currencyPairGroups, function(currencyPairGroup){
wc.price(currencyPairGroup).then(function(res){
let pairs = Object.keys(res);
_.forEach(pairs, function(pair) {
let currentObj = res[pair]
currentObj.pair = pair
currentObj.mid = _.mean([currentObj.bid, currentObj.ask])
console.log('Before saving ' + '\n' +
'this is the pair ' + currentObj.pair + '\n' +
'and this is the bid ' + currentObj.bid + '\n' +
'and this is the ask ' + currentObj.ask + '\n' +
'and this is the mid ' + currentObj.mid + '\n' +
'is the mid a NaN? ' + isNaN(currentObj.mid) + '\n')
savePrice(currentObj)
self.emit('emitPrice', currentObj)
})
})
})
}
Almost always, this works perfectly. Sometimes, however, the currentObj.mid gets passed as NaN and the save validation to Mongoose fails. The console.log looks like this.
this is the pair USD-MXN
and this is the bid 17.90732
and this is the ask 17.91332
and this is the mid NaN
is the mid a NaN? true
I feel like it's an async issue, but I don't think anything in my promise is async. Also, don't know why it works almost every other time. Don't even know what question to ask to figure this out.

Why a reference to object is replaced with its value

I use node.js and express.
I saved on the 'req.session' a complex object that includes array of objects.
In addition I save reference to one of the objects in the array.
For example:
var value = {
name: "name"
, values: []
};
req.session.value = value;
//
// I populate 'req.session.value' with values (with the same structure)
//
// then I save reference to one of the inner objects
var currentValue = req.session.value[3];
//
// later I try to change the save object
//
currentValue.name = "newName";
I expected that if I change the 'currentValue' then the 'req.session.value[3]' will be changed as well. However, for some reason it doesn't happen.
To be concrete, if I change the currentValue immediately after I assign it then the req.session.value[3] is changed but if I am doing it in the next call then just the currentValue is changed.
In the example: I do the assignments to the 'req.session' in the "app.get(...)" if I change the value of the currentValue in the "app.get(...)" it is run ok (the value change in both places) but if I change it in the 'app.post(...)' the only object that change is the currentValue while the req.session.value[3] left the same.
Thanks in advance,
Shai
The code:
'app.get("/template/:templateid/feature/add", isTemplate, function(req, res) {'
' if (!req.session.features) { // if features empty'
''
' // Save the first features level from the current template in the session '
' req.session.features = req.session.template.feature;'
' //'
' if (!req.session.featureNodes) { // featureNotes is a stack/branch of the features'
' req.session.featureNodes = [];'
' }'
' if (!req.query.featureroot || req.query.featureroot == "") {'
' } else {'
' var featureRoot = getFeature(req.query.featureroot, req.session.features); // get one object from req.session.features'
' if (featureRoot) {'
' req.session.featureNodes.push(featureRoot); // save reference'
' var featureR = req.session.featureNodes.pop(); // do check that work!'
' var values = {'
' name: "req.body.name"'
' , description: "req.body.description"'
' , wieght: "req.body.wieght"'
' , created: new Date()'
' , modified: new Date()'
' , feature: []'
' };'
''
' featureR.feature.push(values); // also req.session.features changed'
' req.session.featureNodes.push(featureRoot); // push the reference back for use later'
' } '
' }'
' res.render("addfeature2template.jade", { '
' title: "Add new feature"'
' ,template: req.session.template'
' ,feature: req.session.featureNodes'
' });'
'});'
''
'app.post("/feature/add", isUser, function(req, res) {'
' var SUBMIT = "Create";'
' var CANCEL = "Cancel";'
' switch ( req.param("feature") ) {'
' case SUBMIT:'
' var fields = { name: 1, description: 1, wieght: 1};'
' var values = {'
' name: req.body.name'
' , description: req.body.description'
' , wieght: req.body.wieght'
' , created: new Date()'
' , modified: new Date()'
' , feature: []'
' };'
' if (req.session.featureNodes.length < 1) {'
' req.session.features.push(values);'
' } else {'
' var featureRoot = req.session.featureNodes.pop(); // pop the reference'
' featureRoot.feature.push(values); // change the object but the req.session.features didnt changed '
' }'
' req.session.template = template;'
' res.redirect("/template/" + req.body.templateid);'
' break;'
' case CANCEL:'
' res.redirect("/template/" + req.body.templateid);'
' break;'
' }'
'});'
req.session object is serialized (to store) between the requests.
Example:
Request 1:
req.session = {};
var a = { hello : 'world' };
var b = a;
req.session.a = a;
req.session.b = b;
In this context variables a, b, req.session.a, req.session.b points to one object. You can change field hello in any of these objects, and this will to change in each of them.
After end of request req.session object will be serialized for session storage (memcached, mongodb, etc).
Request 2:
Before request 2 req.session object will be deserialized from storage. Now it contains plain values without references. You can access req.session.a and req.session.b but now it two different objects.

how to set value to incremental variable name?

HI i got 4 flash clocks, that show the different city times, and i am getting the different 4 city times from my php file. after i get new time and minute and second for a city it sending me the information to a function like this :
setFlashvar (hours,minutes,seconds);
so my function will called 4 times. now i need to send that 4 different parameter to my flash clocks like this :
flashvars1 = {thisH:myH,thisM:myM,thisS:myS};
flashvars2 = {thisH:myH + 2,thisM:myM + 2,thisS:myS + 2};
flashvars3 = {thisH:myH + 4,thisM:myM + 4,thisS:myS + 4};
flashvars4 = {thisH:myH + 4,thisM:myM + 4,thisS:myS + 4};
what is the best way to set this all variables with different times what i am getting from function?
thanks in advance.
Variable variables are bad practice. Use an array instead.
flashvars = new Array();
flashvars[0] = {thisH:myH,thisM:myM,thisS:myS};
flashvars[1] = {thisH:myH + 2,thisM:myM + 2,thisS:myS + 2};
....
(or use the notation demonstrated by #Pointy)
and then in the loop
flashvars[i]
var flashvars = [
{thisH:myH,thisM:myM,thisS:myS},
{thisH:myH + 2,thisM:myM + 2,thisS:myS + 2},
{thisH:myH + 4,thisM:myM + 4,thisS:myS + 4},
{thisH:myH + 4,thisM:myM + 4,thisS:myS + 4}
];
Now instead of "flashvars1" you'll use "flasvars[0]". (If you want to start at 1, then you'd just drop a null in before your first object value.)
Also, spaces are free :-)
Here's what your updated function would look like:
function setFlashvar (hours,minutes,seconds){
flashvars.push({ thisH: hours, thisM: minutes, thisS: seconds });
}
That will add another object to the array. You don't need "i" because the array knows its own length.

Categories