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

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

Related

how to convert {obj:"{objects}"} into array with json object inside it

I had % in my cookie and I found following code for it and got the data below after implying that code
var cookies = (document.cookie);
var output = {};
cookies.split(/\s*;\s*/).forEach(function (pair) {
pair = pair.split(/\s*=\s*/);
var name = decodeURIComponent(pair[0]);
var value = decodeURIComponent(pair.splice(1).join('='));
output[name] = value;
});
console.log(output);
The data console is down below;
{"objName":"[{"key":1,"key2":"value 123","key3":"value123"},{"key":1,"key2":"value 123","key3":"value123"}]"}
I have the data as shown above, What I want is to objName into array and remove "" from in front of [] array barckets
objName=[{"key":1,"key2":"value 123","key3":"value123"},{"key":1,"key2":"value 123","key3":"value123"}]
As far as I understand, you are trying to get cookie values, you can try this code and handle the returned array as you need. You can try this solution and let me know if it works.
var cookies = document.cookie.split(';').reduce(
(cookies, cookie) => {
const [name, val] = cookie.split('=').map(c => c.trim());
cookies[name] = val;
return cookies;
}, {});
console.log(cookies);

How do I correctly remove an array of elements from another array?

I have an array of elements that I read in from the DOM like this:
let delete00To04Am = document.getElementById("time000am400amEveryDay").value;
console.log('delete00To04Am');
//this yields: 1669410000000,1669496400000
..
delete00To04Am = delete00To04Am.split(',');
console.log('delete00To04Am: ' ,delete00To04Am);
//this yields: delete00To04Am: ['1669410000000', '1669496400000']
..
timesForAdvert = timesForAdvert.filter((item)=> item !== delete00To04Am )
console.log("timesForAdvert: " ,timesForAdvert);
//this yields: timesForAdvert: [1669482000000, 1669568400000, 1669410000000, 1669496400000]
As you can see nothing was removed from the array.
How do I get timesForAdvert = timesForAdvert.filter((item)=> item !== delete00To04Am ) to work?
Using Array#includes:
const
delete00To04Am = ['1669410000000', '1669496400000'],
timesForAdvert = [1669482000000, 1669568400000, 1669410000000, 1669496400000];
const res = timesForAdvert.filter(item =>
!delete00To04Am.includes(item.toString())
);
console.log(res);
Suggested enhancements to your approach:
const
delete00To04Am = '1669410000000,1669496400000',
timesForAdvert = [1669482000000, 1669568400000, 1669410000000, 1669496400000];
const exclude = delete00To04Am.split(',').map(Number);
const res = timesForAdvert.filter(item => !exclude.includes(item));
console.log(res);

Changing the data of the repeater in wix

I'm trying to manipulate the repeater list in Wix. When the user selects the quantity of equipment, that number of forms show up. I got the hang of it when I see it in the console log but when I try to display it on the web, it gives me an error. I've tried reassigning $w("#repeater1").data to newArr(the new data).
Here's my code
$w("#repeater1").hide();
let itemOptions = $w("#quoteDropdown").options
$w("#quoteDropdown").onChange((event) => {
$w("#repeater1").show();
const arrOfValues = []
let newArr = []
let repeaterData = $w("#repeater1").data;
let quantity = Number(event.target.value);
let iterator = repeaterData.values();
for(const value of iterator) {
arrOfValues.push(value);
}
for(let i = 0 ; i < itemOptions.length; i++) {
newArr = repeaterData.slice(0, quantity);
}
if(quantity > newArr.length) {
let newItems = arrOfValues.filter(arr => {
newArr.forEach(na => arr !== na)
})
newArr.push(newItems)
}
console.log("newArr");
console.log(newArr);
// $w("#repeater1").data is the original data from the repeater
// newArr is the altered data from the repeater based on how it appears based on the users' interaction.
// I've tried each one of these
// $w("#repeater1").data = newArr;
// return newArr;
}); // end onChange
If you're trying to assign the array as the data for a repeater, you need to follow some rules. First, it needs to be an array of objects. Second, each object needs to have an _id property.

Function to format and add object to array not functioning properly

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)

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