Function to format and add object to array not functioning properly - javascript

My component has a state array "bets" consisting of bet objects. The function in question creates an empty "records" array to house formatted records to be stored in the database.
const placeBets = () => {
//determine type of bet(s) - single,parlay,etc.
if(slipType === "single"){
let records = [];
bets.forEach(bet=>{
let tmpModel = formatSingleBet(bet)
records.push(tmpModel);
})
console.log(records);
}
}
I run a for each loop on the bets array to format each bet calling the formatSingleBet function.
//Function to format single bets in records for db storage
const formatSingleBet = (bet) =>{
//create instance of bet model obj and add properties
let betModel = model;
betModel.type = slipType;
betModel.wager = bet.wager;
betModel.odds = bet.odds.decimal;
betModel.result = "";
let legType = bet.type;
if(legType === "Spread"){
//create instance of spread line object
let spread = Spread;
spread.team.type = bet.team.type;
spread.team.name = bet.team.name;
spread.line = bet.handicap;
spread.result = "";
betModel.legs[0].fixtureID = bet.fixtureID;
betModel.legs[0].line = spread;
betModel.legs[0].odds = bet.odds.decimal;
}else if(legType === "3-Way Moneyline"){
//create instance of ML line object
let ml = ML;
ml.team.type = bet.team.type;
ml.team.name = bet.team.name;
ml.result = "";
betModel.legs[0].fixtureID = bet.fixtureID;
betModel.legs[0].line = ml;
betModel.legs[0].odds = bet.odds.decimal;
}else if(legType === "Total"){
//create instance of Total line object
let total = Total;
total.result = "";
total.bet = bet.bet;
total.line = bet.total;
betModel.legs[0].fixtureID = bet.fixtureID;
betModel.legs[0].line = total;
betModel.legs[0].odds = bet.odds.decimal;
}
return {
contestPlayerID: match.params.entryid,
jsonBet: betModel
};
}
I create an instance of the model object, and set the properties depending on the "leg type" of the bet. I then return the formatted bet to be inserted into the records array which is then returned.
The issue is that regardless of the differences in the bet, the betModel object is always returned as the last bet in the bets array.
One thing I noticed is that when I log the betModel it appears to be different for each bet, however the property values change when drilling into the object.
Please help, any advice would be wonderful.

By assigning betModel = model you are simply creating a reference to model and all the changes you make to betModel will also be made to model. This means that model is not a blank prototype, but contains the values of the last bet that you processed.
In order to use model as a prototype in the way you seem to intend use spread syntax to assign a copy to betModel.
let betModel = {...model}
const spreadSource = { a: 1, b: 2 };
const spread = {...spreadSource};
spread.c = 'Added'
console.log('spread: ', spread);
console.log('spreadSource: ', spreadSource);
const referenceSource = { a: 1, b: 2 };
const reference = referenceSource;
reference.c = 'Added';
console.log('reference: ', reference)
console.log('referenceSource: ', referenceSource)

Related

How to prevent Data in const to change if underlaying data changes

I am running into a strange issue. I have a function that updates my data on a Couchbase back end and before I do so I query if we have the record or if will be a new one. In my code I check via if (docid[1].metrics.resultCount === 1) if we have a record or not and then I assign the result to const originalData via const originalData = docid[0][0].Record. So far so good, if I print to my console the data at that point the data is correct. But if I go and print it after some changes where made to the docid[0][0] it also seems to update the originalData. Question is how can I store the Data in const originalData without being effected by changes to the docid[0][0]?
case '2':
// Title Pro Farm Updates or Inserts
// Get the Translation Template
const templateId = "c90207b5-71d1-43d6-b644-f92cf415ecab"
const mappings = await couch.getDoc('contacts', 'import_mapping::' + templateId)
const data_map = mappings.result.value
// Transform based on mappings
let map_result = mapdata(data_map , json)
// TODO: Remove Debug Print Out
//console.log(JSON.stringify(map_result))
myApn = json.APN
// Strip Dashes from APN String
myApn = myApn.replace(/-/g, "")
// Get the DocId for the Doc which matches APN
docid = await couch.n1qlQuery_wId('contacts', myN1qlStr, [myApn])
if (docid[1].metrics.resultCount === 1) {
const originalData = docid[0][0].Record
console.log('Before Updates')
console.log(originalData)
DocId = docid[0][0].DocId
console.log(' We are updating APN ' + myApn)
// get update Object based on Import
let update = await imp_help.farm_update_titlepro(map_result, res.locals.decoded.user_guid)
// console.log(docid[0][0])
// Mailing Address
let MailingAddrObj = update.mailingAddress
Object.keys(MailingAddrObj).forEach(key => MailingAddrObj[key] === undefined && delete MailingAddrObj[key])
let MailingAddress = _.extend(docid[0][0].Record.mailingAddress, MailingAddrObj)
// Owner Section
let OwnerObj = update.Owners
Object.keys(OwnerObj).forEach(key => OwnerObj[key] === undefined && delete OwnerObj[key])
let Owner = _.extend(docid[0][0].Record.Owners, OwnerObj)
// Sales Info
let SalesInfoObj = update.SalesInfo
Object.keys(SalesInfoObj).forEach(key => SalesInfoObj[key] === undefined && delete SalesInfoObj[key])
let SalesInfo = _.extend(docid[0][0].Record.SalesInfo, SalesInfoObj)
// Tax Info
let TaxesObj = update.Taxes
Object.keys(TaxesObj).forEach(key => TaxesObj[key] === undefined && delete TaxesObj[key])
let Taxes = _.extend(docid[0][0].Record.Taxes, TaxesObj)
// History
let HistoryObj = update.History
Object.keys(HistoryObj).forEach(key => HistoryObj[key] === undefined && delete HistoryObj[key])
let History = _.extend(docid[0][0].Record.History, HistoryObj)
// Farm Object
let FarmObj = update
Object.keys(FarmObj).forEach(key => FarmObj[key] === undefined && delete FarmObj[key])
let Farm = _.extend(docid[0][0].Record, FarmObj)
console.log('After Updates')
console.log(originalData)
Farm.mailingAddress = MailingAddress
Farm.Owners = Owner
Farm.emails = []
Farm.phones = []
Farm.SalesInfo = SalesInfo
Farm.Taxes = Taxes
Farm.History = History
console.log(Farm)
//let upsertResult = await couch.upsertDoc('contacts', DocId, Farm)
// console.log(upsertResult)
}
else if (docid[1].metrics.resultCount == 0) {
console.log("No Record Found")
console.log(' We are creating New APN ' + myApn)
// get update Object based on Import
let newRecord = await imp_help.farm_create_titlepro(json, res.locals.decoded.user_guid)
DocId = newRecord._type + "::" + newRecord._id
console.log(DocId)
let upsertResult = await couch.upsertDoc('contacts', DocId, newRecord)
console.log(upsertResult)
}
break;
In JavaScript, when we assign one object to another, such as in your case, we'll have a copying by reference, because both variables are assigned to reference the same object. Hence, the following code will result in the following output:
const ghostbusters = {number: 4};
const tmnt = {number: 4};
let fantastic4 = tmnt;
So, changing fantastic4 will be like changing tmnt which will result in that error. This is not the case for primitives like strings and numbers.
For your case, to avoid this, you should use Object.assign or spread operators.
const tmnt = {number: 4};
const fantastic4 = {...tmnt};
I suggest you try this:
const originalData = {...docid[0][0].Record}
// or
const originalData = Object.assign({}, docid[0][0].Record)
This will create a clone of your data instead of referencing the same one.
you should use Object.assign like below:
const originalData = Object.assign({}, docid[0][0].Record);
it makes a copy of the object

how to choose a random item from arrays nested in an object

I'm trying a project that will choose a random answer out of one of the 3 nested arrays in my object. My goal is to know afterwards out of which array the answer came, so I can use that to know what the new sentence will be.
The example below works with 1 array, but i want to know if the answer is a good, bad or doubt answer, hence why i put it in an object.
EDIT: code below gives me a random property in my object, but i need to go one step deeper. The comment next to it is what i tried but it gives me undefined.
const randomAnswers = {
goodAnswers: ['yes','Absolutely','certainly',"I'm sure",'HELL YES'],
maybes: ['maybe','probably','perhaps',"honestly man, i really don't
know this one"],
badAnswers: ['LOL NO','no way man','maybe',"forget it",'HELL no','Are
you serious?']
};
{
const init = () => {
console.log("initiated");
let answer = document.querySelector('.answer');
answer.style.opacity = 0;
setTimeout(fixSentence,3000);
//fixSentence();
}
const fixSentence = () => {
let a = document.querySelector('.answer');
let think = document.querySelector('.think');
console.log('shown');
console.log(a.textContent);
let randomAnswer = randomAnswers[Math.floor(Math.random()*randomAnswers.length)];
var randomProperty = function (obj) {
var keys = Object.keys(obj)
let random = obj[keys[ keys.length * Math.random() << 0]];
return random/*[Math.floor(Math.random()*randomAnswers.length)]*/;
};
console.log(randomProperty(randomAnswers))
let splittedSentence = a.textContent.split(" ");
console.log(splittedSentence);
a.textContent = `${randomAnswer}`;
a.style.opacity = 1;
think.style.opacity = 0;
}
init();
}
the output of console.log(randomAnswer) is obviously undefined right now, but I can't figure out how to choose a random item out of one of the three arrays in the object.
You could do something like this:
const randomAnswers = {
goodAnswers: ['yes','Absolutely','certainly',"I'm sure",'HELL YES'],
maybes: ['maybe','probably','perhaps',"honestly man, i really don't know this one"],
badAnswers: ['LOL NO','no way man','maybe',"forget it",'HELL no','Are you serious?']
};
const randomNumber = function(subject) {
return Math.floor(Math.random()*subject.length);
}
const types = Object.keys(randomAnswers);
const randomTypeNumber = randomNumber(types);
const randomType = types[randomTypeNumber];
const randomAnswerNumber = randomNumber(randomAnswers[randomType]);
const randomAnswer = randomAnswers[randomType][randomAnswerNumber];
console.log( { randomType, randomAnswer } );
You pick a random key from the object, and then pick a random element from that array by using Object.keys(randomAnswers).length and subsequently that array length for the random numbers.

iterate through Json array and get nested object's value Typescript

I have an array with to access a list of properties which i have manage to get the value of these properties however, there is a nested object "Region" in the list which has a specific property "regionName" that i would like to retrieve the value, please check the code and uploaded images for reference.
I hope to this made sense. Thank You in advance
export function CreateStores(xhttp: XMLHttpRequest, storeArray?: Array<PromotionClasses.Store>) {
while (STORE_TABLE.rows.length > 1) {
STORE_TABLE.deleteRow(1);
}
if (storeArray == undefined) {
//Convert the response into an array of objects
storeArray = JSON.parse(xhttp.responseText) as Array<any>;
}
CheckForDuplicateStores(storeArray);
//Get the current row length of the table so we know where to append to
let tableRowLength = STORE_TABLE.rows.length as number;
console.log("Store array is");
// console.log(storesInPromotionArray);
for (let i = 0; i < storeArray.length; i++) {
//A dictionary containing the key value pair of the stores properties
let tableData = {};
//Add the store's id to the storeArray
let store = new PromotionClasses.Store(storeArray[i]["StoreName"], storeArray[i]["id"]);
storesInPromotionArray.push(store);
console.log(storeArray[i]["region"]);
var check = storeArray[i]["region"];
//let attr = new PromotionClasses.Attribute(storeArray[i].name, storeArray[i].type, storeArray[i].property);
//Assingattributes.push(attr);
//Create and insert a new row
let row = STORE_TABLE.insertRow(tableRowLength);
//row.contentEditable = 'true'
//The first three cells will always be the row number, store number and name
tableData["#"] = i.toString();
tableData["Number"] = storeArray[i]["storeNumber"];
tableData["Name"] = storeArray[i]["storeName"];
tableData["addressLine"] = storeArray[i]["addressLine"];
tableData["postcode"] = storeArray[i]["postcode"];
//****NESTED OBJECT PROPERTY = regionName
tableData["region"] = storeArray[i]["region"];

Add items to a Javascript object

My app is hitting a WebAPI that returns some JSON records. I get them via jQuery AJAX and assign the JSON to a JavaScript variable. I can loop through and make changes to existing items without issue. However, how do I add more "records" to this object? I'm trying to understand the structure of the resulting variable.
Here is what I have as a test. Is this the best way?
var trustAccounts = {"accounts":[
{"entityId":12345,
"type":"IOLTA",
"nameOnAccount":"Sam Smith Trust",
"accountNumber":"987654",
"bankCode":"003",
"bankName":"Bank of Stuff",
"accountDate":"12/15/2014",
"status":"A",
"exempt":"N",
"accountId":142922,
"action":"U"}]};
var newaccount = {};
newaccount.entityId = 23456;
newaccount.type = "IOLTA";
newaccount.nameOnAccount = "John Smith Trust";
newaccount.accountNumber = "789456";
newaccount.bankCode = "003";
newaccount.bankName = "Bank of Stuff";
newaccount.accountDate = "12/15/2014";
newaccount.status = "A";
newaccount.exempt = "N";
newaccount.accountId = 142923;
newaccount.action = "U";
trustAccounts.accounts.push(newaccount);
console.log(trustAccounts);
So if we name the returned variable object we can simply create new elements using object.newItemName. Eg below:
object.newItemName = 'Hello World'
You just add them, as if they already existed. A JSON-parsed object is just a normal JavaScript object.
let obj = {};
obj.newProp = 5;
console.log(obj.newProp); // 5
obj['newProp'] = 4;
console.log(obj.newProp); // 4
You can set them in two ways, with the dot-notation or with square brackets ([]). The dot-notation way, the value after the dot is what it's called. The square bracket can accept a string or variable, so you can use it to set a property to a specific name.
If you need to nest things, you have to create each level. For example, if you wanted to set obj.something.aValue, you could do something like this:
let obj = {};
obj.something = {};
obj.something.aValue = 5;
Or, you can also do it in fewer shots, depending what you're doing:
let obj = {
something: {
aValue = 5;
}
};

How to stock array with localStorage (Chrome Extension)?

I tried to stock an array in localStorage but then I read it was impossible. So I tried that:
array = {};
array.name = $('[name="name"]').val();
array.username = $('[name="username"]').val();
array.password = $('[name="password"]').val();
alert(localStorage['accounts']);
local = JSON.parse(localStorage['accounts']);
localu = local.push(array);
alert(JSON.stringify(localu));
In fact the scripts stops at the first alert which returns '[]' (I previously put that value to check the result).
Why isn't my script working?
JavaScript, {} is an Object. [] is an Array.
var array = [] and var array = new Array() do the same thing.
An array is an ordered container of stuff, each value has an index not a key.
An object is a named container of stuff, each "stuff" has a key.
Your array is definitely an object.
var data = {};
data.name = $('[name="name"]').val();
data.username = $('[name="username"]').val();
data.password = $('[name="password"]').val();
alert(localStorage['accounts']);
// > undefined OR the value
local = JSON.parse(localStorage['accounts']);
// local contains a parsed version of localStorage['accounts']
localu = local.push(array);
// localu = 0 (push returns the length i think?)
alert(JSON.stringify(localu));
Try the following. I've not tested it, but might work.
var data = {};
data.name = $('[name="name"]').val();
data.username = $('[name="username"]').val();
data.password = $('[name="password"]').val();
if (localStorage['accounts'] == undefined) { // fixed
// does the key exist? No so create something to get us started
localu = { accounts: [] };
} else {
// the key exists! lets parse it
localu = JSON.parse(localStorage['accounts']);
}
// add the new "data" to the list
localu.accounts.push(data);
// save the results (we have to stringify it)
localStorage['accounts'] = JSON.stringify(localu);

Categories

Resources