Javascript object assigning - javascript

I have an object coming to my VueJS front-end and I need to assign it to a large form with many v-models, which will then submit a new object to the backend. The NEW PARCEL in this photo represents the v-models and the OLD PARCEL is how it is coming from the backend:
My problem is I can't find a way to assign the properties to the NEW PARCEL accurately without doing it line by line, as the properties are nested differently based on address and keyedData:
this.newParcel.state = parcel.address.parsed_state
this.newParcel.zip = parcel.address.parsed_postal
this.newParcel.onSiteContactName = parcel.keyedData.onSiteContactName
^ Only 4/52! If anyone notices a simpler way to do this, my code would love it! It's quite gnarly to have so many lines of code to achieve the desired effect.
this.newParcel.onSiteContactEmail = parcel.keyedData.onSiteContactEmail

To make assigning a new structure less verbose, you could create some reference fields, and assign a new object using those.
eg..
const parcel = {
address: {
parsed_state: "State",
parsed_postal: "Postal"
},
keyedData: {
onSiteContactName: "On site contact name"
}
};
const addr = parcel.address; //ref var for address
const keyd = parcel.keyedData; //ref var for keyedData
const newParcel = {
state: addr.parsed_state,
zip: addr.parsed_postal,
onSiteContactName: keyd.onSiteContactName
};
console.log(newParcel);

Related

Looping through a JSON array and push the values into an array variable using node.js

I'm trying to create a chatbot in Dialogflow using node.js. The training phrases will come from a JSON file.
example JSON:
{
"Training_Phrases": ["How can I help you?", "How can I assist you today?"]
}
The Training phrases is being added on the intent created but the two phrases are merged in a single line instead of being two separate phrases.
Here is the current code that I have. The inputPhrases obj is the JSON file:
async function createIntent(inputPhrases) {
const displayName = ('Intent: ' + intentName);
//create training phrases
const trainingPhrases_Parts = [inputPhrases];
const trainingPhrases = [];
trainingPhrases_Parts.forEach(Phrases_Part => {
const part = {
text: Phrases_Part,
};
// Here we create a new training phrase for each provided part.
const trainingPhrase_con = {
parts: [part],
};
console.log(part);
trainingPhrases.push(trainingPhrase_con);
});
//CONSTRUCT THE INTENT
const intent = {
displayName: displayName,
trainingPhrases: trainingPhrases,
messages: [message],
};
const emptyArray = [];
Training_Phrased.forEach((text)=>{emptyArray.push(text)})
Also from your current code, what you're trying to achieve is not to clear but at this point you are pushing the whole object into the array and not the property of the object "parts" which actually stores the array.
trainingPhrases.push(trainingPhrase_con);
This should be trainingPhrases.push(trainingPhrase_con.parts); If you're are trying to store the parts in the trainingPhrases array.

JS map to translate values back and forth

I'm trying to figure out the best way to approach mapping values back and forward as a sort of translation process. The use case is having to process a non SEO friendly attribute code into a nicer format and display that on the frontend, but i also need to be able to process the nice attribute label back into original code so i can use that in my script. In the following example, i'd want to be able to look up myMap to check if a string value exists in the object, and if it does, pull out its corresponding label.
var myString = 'color_attr_code'; // Want to be able to extract 'color' from the map
var myAltString = 'color'; // Want to be able to extract 'color_attr_code'
var myMap = {
'color_attr_code': 'color'
}
Thanks for any help.
You're on the right track, though in modern environments you might use a Map rather than an object, or at least create the object without a prototype so there aren't false matches on toString or valueOf or other things the default object prototype provides.
You'd have two maps, one going each direction, probably best derived from the same source data:
const mappings = [
["color_attr_code", "color"],
["blah_attr_code", "blah"],
// ...
];
const attrToLabel = new Map(mappings);
const labelToAttr = new Map(mappings.map(([key, value]) => [value, key]));
Then you use attrToLabel.get("color_attr_code") to get the corresponding label, and labelToAttr.get("color") to get the corresponding code.
Live Example:
const mappings = [
["color_attr_code", "color"],
["blah_attr_code", "blah"],
// ...
];
const attrToLabel = new Map(mappings);
const labelToAttr = new Map(mappings.map(([key, value]) => [value, key]));
console.log(`Label for "color_attr_code": ${attrToLabel.get("color_attr_code")}`);
console.log(`Code for "color": ${labelToAttr.get("color")}`);
Or in ES5 (although really, in today's world, there's no reason to write ES5 manually — write modern code and transpile with Babel or similar) and objects:
var mappings = [
["color_attr_code", "color"],
["blah_attr_code", "blah"],
// ...
];
var attrToLabel = Object.create(null);
var labelToAttr = Object.create(null);
mappings.forEach(function(mapping) {
var code = mapping[0], label = mapping[1];
attrToLabel[code] = label;
labelToAttr[label] = code;
});
Then you use attrToLabel["color_attr_code"] to get the corresponding label, and labelToAttr["color"] to get the corresponding code.
Of course, all of this assumes there are always just 1:1 mappings, that there aren't (for instance) two codes that both map to the same label.

Node.js best practice to populate JSON request

Intro
I'm currently using the UPS Rate API to create a shipping plugin for a client to get an estimate on shipping charges for customers during checkout (among other things).
I've briefly used Nodejs in the past, however this would be my first time using it in a production environment, and I want to ensure I'm using best practices for this application.
Code
Below is the request I must send to UPS' API endpoint to get a shipping estimate:
{
"UPSSecurity":{
"UsernameToken":{
"Username":"Your User Id",
"Password":"Your Password"
},
"ServiceAccessToken":{
"AccessLicenseNumber":"Your Access License"
}
},
"RateRequest":{
"Request":{
"RequestOption":"Rate",
"TransactionReference":{
"CustomerContext":"Your Customer Context"
}
},
"Shipment":{
"Shipper":{
"Name":"Shipper Name",
"ShipperNumber":"Shipper Number",
"Address":{
"AddressLine":[
"Address Line ",
"Address Line ",
"Address Line "
],
"City":"City",
"StateProvinceCode":"State Province Code",
"PostalCode":"Postal Code",
"CountryCode":"US"
}
},
"ShipTo":{
"Name":"Ship To Name",
"Address":{
"AddressLine":[
"Address Line ",
"Address Line ",
"Address Line "
],
"City":"City",
"StateProvinceCode":"State Province Code",
"PostalCode":"Postal Code",
"CountryCode":"US"
}
},
"ShipFrom":{
"Name":"Ship From Name",
"Address":{
"AddressLine":[
"Address Line ",
"Address Line ",
"Address Line "
],
"City":"City",
"StateProvinceCode":"State Province Code",
"PostalCode":"Postal Code",
"CountryCode":"US"
}
},
"Service":{
"Code":"03",
"Description":"Service Code Description"
},
"Package":{
"PackagingType":{
"Code":"02",
"Description":"Rate"
},
"Dimensions":{
"UnitOfMeasurement":{
"Code":"IN",
"Description":"inches"
},
"Length":"5",
"Width":"4",
"Height":"3"
},
"PackageWeight":{
"UnitOfMeasurement":{
"Code":"Lbs",
"Description":"pounds"
},
"Weight":"1"
}
},
"ShipmentRatingOptions":{
"NegotiatedRatesIndicator":""
}
}
}
}
Seeing the amount of fields to fill out, whats the best way to approach this, while adhering to basic software engineering principles of low coupling and high cohesion?
Should I do something similar to the code example below, but for each field section?
const shipToAddr1 = "A street with number"
const shipToAddr2 = "Line 2 with number"
const shipToAddr3 = "The third line"
const shipToCity = "Boston"
const shipToStateProvinceCode = "12"
const shipToPostalCode = "01970"
const shipToCountryCode = "US"
const shipToName = "Bob Wallace"
const packageLength = "10"
const packageWidth = "5"
const packageHeight = "18"
const PackageWeight = "12"
//See above code snippet
var jsonRequest = {...}
function writeShipToContents(json, shipToName, shipToAddr1, shipToAddr2,
shipToAddr3){
json.RateRequest.Shipment.ShipTo.Name = shipToName
json.RateRequest.Shipment.ShipTo.Address.AddressLine = [
shipToAddr1,
shipToAddr2,
shipToAddr3
]
}
function writeShipFromContents(json){
...
}
function writePackageDetails(json){
...
}
function writeShipmentRequest(json){
writeShipToContents(json)
writeShipFromContents(json)
writePackageDetails(json)
...
return json
}
writeShipmentRequest(jsonRequest)
My instinct is that many things are wrong with the above code, for instance having each function change the referenced object instead of returning a new object with the populated contents; having the functions use global variables to populate the information; and all in all, this seems like a lot of code for a simple task.
The application will take a POST request with the information as const in the example, then return the results of the shipping estimate.
Should I be creating a dictionary of each field, pass the json and the dictionary contents, and have the function lookup the dictionary items, populate the json, and return the results?
Don't overthink this with unnecessary programming paradigms. According to your comment this is a simple creation of an object whose structure never changes. Treat it as such.
If your task is to create a Javascript Object from values and send it in a POST request, simply create a Javascript Object with the short notation:
const upsPostBody = {
property: value
}
Do this for the whole object, e.g. (excerpt):
const username = 'Your User Id';
const password = 'Your Password';
const accessLicenseNumber: 'Your Access License';
const upsPostBody = {
UPSSecurity:{
UsernameToken: {
Username: username,
Password: password
},
ServiceAccessToken: {
AccessLicenseNumber: accessLicenseNumber
}
}
// Continue for all other keys and values
}
After assigning the values to the object, pass the object as the body to your POST method.
The first thing to use best practice is to use object literals instead of polluting global namespace
`const anyObject = {
// your object
}`
the second thing is to use functional programming techniques
`function( anyObject, argsToDo) {
// do what every you want to anyObject with other functions
// anyObject could contain all the properties you need to write
// () => setWhatever(anyObject)
// or return new anyObjectWithArgsToDo();
}`
you can use the approach to write the fields dynamically for the JSON object that you need to submit example pseudocode:
`function writeFields( anyObject, fieldsObject ) {
let i = 0;
foreach( anyObject as value ) {
value = fieldsObject[I];
i++;
}`
you can combined objects to hold other objects JSON stands for JavaScript Object Notation so you can pass them as an argument to functions, perform operations on them with functions, create new Objects with objects as arguments et. cetera. Here is a link to the Wiki on functional programming https://en.wikipedia.org/wiki/Functional_programming. To use modern programming techniques would be to use a layer of abstraction and encapsulation among other things, it appears as though you are writing to the implementation instead of writing reusable code that performs a task. The best way to write the code is so that it would work with any object, that involves the use of functional programming techniques where the function does not care about the state of it's arguments. Example
`function writeSomeObject ( object, property, value) {
object[${property}] = ${value}; // use back ticks
// that allow dynamic use of arguments
}`
I hope that helps

Add [DataObject] to exsisting array with var key

Using Cordova, I am trying to get an Object to add to an array. I have this working on node JS using :
theData = {[varkey]:DataObject};
But I can't get this to work the same way within my javascript that cordova runs.
I need to do the following:
var TownName = 'Auckland', var townData = (JSON Data);
theArray = new Array();
theArray[TownName] = townData;
I need to be able to call it back as:
theArray['Auckland']
Which will return (JSON Data)
But it doesn't want to store the data with the key inside the array.
I have also tried:
theArray.TownName = townData;
theArray = [{TownName:townData}];
theArray = {[TownName]:townData}];
Nothing wants to store the data.
Any suggestions?
::EDIT::
data.theData =
"Auckland"[
{
"username":"pndemoname1",
"number":"373456",
"www":"http://373456.pndemoname1",
"icon":"/imgs/pndemoname1.png"
},
{
"username":"pndemoname2",
"number":"373458",
"www":"http://373458.pndemoname2",
"icon":"/imgs/pndemoname2.png"
}
data.town = "Auckland";
townData = new Array();
alert(JSON.stringify(data.theData))//Alerts theData
townData[data.town] = data.theData
alert(townData[townName]) //Alerts undefined
::EDIT2::
Re-defining the array within the function that deals with all of the data, seems to make it work.
As per my answer, the issue was that I assumed javascript vars are global.
Use objects or an array of objects.
A data structure like this:
{
town1: town1Data,
town2: town2Data,
}
Or more common:
[
{
name: "Town 1",
data: {...}
},
{
name: "Town 2",
data: {...}
},
]
For reference:
http://andrewdupont.net/2006/05/18/javascript-associative-arrays-considered-harmful/
I got what you're trying to do, to add property names dynamically to your object is first, by making sure you are using an OBJECT instead of an array, so when you want to store something you will do the following:
var _obj = {}, _something = 'xyz';
_obj[ _something ] = { ... }; // json structure
The problem you're facing is that you want to assign a string value as a key inside your array, which will not work.
However, you can still use the array you defined and do the following:
var _array = new array();
_array.push( { .... } ); // insert json structure
Remember! By using the array you will have to loop through all values every time you want to access your key, just as the best practice to avoid getting into errors.
Good luck.
The issue was that I didn't define the array within the function of where I was trying to add the information to.
I assumed the var was global (Too much PHP)

Add new key value pair to existing Firebase

This might be a pretty basic question, but so far I can't find the answer to my problem online after much googling. I have a firebase web app where the data structure is pretty simple. Initially, it's empty, like this:
fireRef {
}
I want to be able to add key value pairs where the key is created by the user and the value is just some text. For instance, the user would enter their name as the key, and the value as their age. Then I want to send that data to the server and have the firebase now look like this:
fireRef {
John : 25,
}
I can accomplish this one addition with:
var name = getUserName();
var age = getUserAge();
var node = {};
node[name] = age;
fireRef.set(node);
However, I want multiple people to be able to do this. When I try to add a new person to the server, the old "John : 25" pair turns red and disappears, leaving only the new key value pair.
How can I keep both around, and maintain a dataset of a bunch of key, value pairs?
The unique id in firebase is generated when we push data.
For example:
var fireRef = new Firebase('https://<CHANGE_APP_NAME>.firebaseio.com/fireRef');
var newUserRef = fireRef.push();
newUserRef.set({ 'name': 'fred', 'age': '32' });
Another way is to directly set the child elements:
var fireRef = new Firebase('https://<CHANGE_APP_NAME>.firebaseio.com/fireRef');
fireRef.child(1).set({'name':'user2','age':'34'});
fireRef.child(2).set({'name':'user3','age':'24'});
#user3749797, I got confused with this exact problem.
#learningloop offered a good solution, because it achieves the task of adding data to your firebase, but there is an option to add a new k,v (name, age) pair into a single JSON associative array rather than push to an array of associative arrays. Effectively, #learningloop sees:
[
{
name: steve,
age: 34
},
{
name: mary,
age: 22
}
]
Perhaps his way is better, but you and I were looking for this:
{
steve: 34,
mary: 22
}
I've managed to add to this list of k,v pairs with
var fireRef = new Firebase('https://<CHANGE_APP_NAME>.firebaseio.com/fireRef');
fireRef.update({ 'jobe': '33'});
Yielding
{
steve: 34,
mary: 22,
jobe: 33
}
In my firebase.
Full documentation on saving to firebase [here]
Just to add bit more clarity to #Charlie's answer:
Following works for me:
admin.database().ref(SITE).child("ChildName").child("2ndLevelChild") .update({[KeyVariable]:valueVariable});
Aparently if I were to use it like the following it doesnt work (it overwrites:
var newChild = {};
newChild["ChildName/" + "2ndLevelChild"] = {
[KeyVariable]: valueVariable
};
admin.database().ref(SITE).update(newChild);

Categories

Resources