Merge/Overwrite JS object with object derived as JSON from POST request - javascript

I got the following obj that I use to store setting parameters. It holds default values I wanna make the properties of this obj be overwritten by a JSON that comes in via POST request. Sure, I can convert every string value from the JSON indivually and assign it to the corresponing property, however, whats a good practise for that?
const moth_eng = require('./fractioning_model_v1.1.js');
// in ./fractioning_model_v1.1.js set default values
var settings = {
i: 1,
rev_share: 0.2,
parent_level_share: 0.45,
d: 2,
get user_pool_share () {return this.i - this.rev_share;},
get remaining_levels_pool () {return this.user_pool_share - this.parent_level_share;},
};
//main.js
app.post('/fractobj', function (req, res) {
logger.log("info", "/fractobj requested - post")
let obj = req.body;
moth_eng.set_sttngs(obj);
res.send(moth_eng.getFractions(10));
});
// in ./fractioning_model_v1.1.js
function setSettings(obj){
Object.assign(settings, obj);
}
My Problem is, that the Object.assign() does assign the values as strings, since the values of the JSON are string and I find it uncool to individually convert those values for each value.
Whats a proper way to solve this problem in the big picture?

Related

How do I set multiple values of a JSON object?

So I've been working on this project but I'm stuck because I can't figure out how I should go about setting the other values of this new JSON object. So basically on the front end I have this:
HTML page view. The 'cat4' ID is the new object I tried to create, and illustrates the error I'm trying to fix. The problem is that I'm having trouble setting the LIMIT value of newly created objects (or multiple values at all). Here is the code where the object is created:
function sendCat()
{
window.clearTimeout(timeoutID);
var newCat = document.getElementById("newCat").value
var lim = document.getElementById("limit").value
var data;
data = "cat=" + newCat + ", limit=" + lim;
var jData = JSON.stringify(data);
makeRec("POST", "/cats", 201, poller, data);
document.getElementById("newCat").value = "Name";
document.getElementById("limit").value = "0";
}
In particular I've been playing around with the line data = "cat=" + newCat + ", limit=" + lim; but no combination of things I try has worked so far. Is there a way I can modify this line so that when the data is sent it will work? I find it odd that the line of code works but only for setting one part of the object.
The JSON.stringify() method converts a JavaScript object or value to a JSON string, optionally replacing values if a replacer function is specified or optionally including only the specified properties if a replacer array is specified.
MDN
I think this is what you want:
const newCat = 'Meow';
const newLimit = 5;
const data = {
cat: newCat,
limit: newLimit
}
console.log(JSON.stringify(data));
What you're referring to as a 'JSON object' is actually just a javascript object, you can make one using object literal syntax. An object literal with multiple properties looks like this:
var data = {
cat: newCat,
limit: lim
};
makeRec("POST", "/cats", 201, poller, JSON.stringify(data));
assuming the fifth parameter to makeRec is supposed to be the POST request body as stringified JSON, as your code seems to imply

JavaScript selecting Object Arraylike?

The Problem is the following:
I have a JSON file that has objects with the following name: "item0": { ... }, "item1": { ... }, "item2": { ... }. But I can't access them when going through an if method.
What I've done so far:
$.getJSON('/assets/storage/items.json', function(data) {
jsonStringify = JSON.stringify(data);
jsonFile = JSON.parse(jsonStringify);
addItems();
});
var addItems = function() {
/* var declarations */
for (var i = 0; i < Object.keys(jsonFile).length; i++) {
path = 'jsonFile.item' + i;
name = path.name;
console.log(path.name);
console.log(path.type);
}
}
If I console.log path.name it returns undefined. But if I enter jsonFile.item0.name it returns the value. So how can I use the string path so that it's treated like an object, or is there an other way on how to name the json items.
As others stated 'jsonFile.item' + i is not retrieving anything from jsonFile: it is just a string.
Other issues:
It makes no sense to first stringify the data and then parse it again. That is moving back and forth to end up where you already were: data is the object you want to work with
Don't name your data jsonFile. It is an object, not JSON. JSON is text. But because of the above remark, you don't need this variable
Declare your variables with var, let or const, and avoid global variables.
Use the promise-like syntax ($.getJSON( ).then)
Iterate object properties without assuming they are called item0, item1,...
Suggested code:
$.getJSON('/assets/storage/items.json').then(function(data) {
for (const path in data) {
console.log(data[path].name, data[path].type);
}
});
What you want is to use object notation using a dynamic string value as a key instead of an object key. So, instead of using something like object.dynamicName you either have use object[dynamicName].
So in your example it would be like this.
path = 'item' + i;
jsonFile[path].name
I'm afraid you cannot expect a string to behave like an object.
What you can do is this:
path = `item${i}`
name = jsonFile[path].name

How to get the GET request passed list data?

If I use the params for pass a list in GET method:
fetch_physicalserver_list(){
var params = {
id_list: this.physicalserver_id_list // there is [24, 26, 27]
}
this.$Lml_http('get', this.$Api_urls.user_productmanage_physicalserver.list(), params, response => {
this.physicalserver_list = response.data.results
console.log( response.data.results)
}, error => {
})
}
And in the request, the id_list convert to the id_list[]=24&id_list[]=27&id_list[]=27.
and I don't know how to get the id_list in the backend.
I use the method to get the id_list[] I will only get the first id, if I get id_list, I will get nothing.
the code of get_param_from_query_params method:
def get_param_from_query_params(query_params, param):
param_temp = None
try:
mutable = query_params._mutable
query_params._mutable = True
param_list = query_params.pop(param)
param_temp = param_list[0] if (isinstance(param_list, list) and len(param_list) > 0) else ''
query_params._mutable = mutable
except Exception as e:
pass
return param_temp
So, I have two questions:
1.The params's id_list converted to id_list[]. where is the official description?
2.How can I get the id_list after I passed to the backend?
Firstly, you are using the key id_list[], so you must use id_list[] to retrieve the key in Django. Including [] in JavaScript is a convention to show there are multiple values, but it makes no difference to Django.
If you want a list of values instead of a single value, then use pop_item instead of pop.
It's not clear to me why you need the get_param_from_query_params method. You are returning param_list[0] which means you'll only ever get a single item. It would be much simpler to use getlist:
id_list = query_params.getlist('id_list')

Store values in javascript object with same keys

I have the following code to extract values from a JSON response. What I am trying to do is store the data in a similar way to how you would with an associative array in php. Apologies for the code being inefficient. The array comments written down are how I would like it to look in the object.
$.each(responseData, function(k1,v1){
if(k1 == "0"){
$.each(v1, function(k2,v2){
$.each(v2, function(k3, v3){
if(k3 == "val"){
//store in object here
//Array1 = array("time"=>k2, "iVal"=>v3)
console.log(k3 + v3 + k2);
}else{
//Array2 = array("time"=>k2, "aVal"=>v3)
console.log(k3 + v3 + k2);
}
});
});
}
});
So all the information is there but I am not sure how to store each instance for the values in an object. I did try store it like this:
//obj created outside
obj1.date = k2;
obj2.iVal = v3;
But doing this clearly overwrote every time, and only kept the last instance so I am wondering how can I do it so that all values will be stored?
Edit: Added input and output desired.
Input
{"0":{"18.00":{"iVal":85.27,"aVal":0.24},"19.00":{"iVal":85.27,"aVal":0.36},"20.00":{"iVal":0,"aVal":0}}, "success":true}
Desired output
array1 = {"time":"18.00", "iVal":85.27},{"time":"19.00", "iVal":85.27},{"time":"20.00", "iVal":0}
array2 = {"time":"18.00", "aVal":0.24},{"time":"19.00", "aVal":0.36},{"time":"20.00", "aVal":0}
try this :
var g1=[];
var g2=[];
for ( a in o[0])
{
g1.push({time:a , iVal:o[0][a]['iVal']})
g2.push({time:a , aVal:o[0][a]['aVal']})
}
http://jsbin.com/qividoti/3/edit
a json response can be converted back to a js object literal by calling JSON.parse(jsonString) inside the success callback of your ajax call.
from then on there is no need for iterating over that object since you navigate it like any other js object which is can be done in two ways either
the js way -> dot notation
var obj = JSON.parse(jsonStirng);
var value = obj.value;
or like a php array
var value = obj["value"];

HTML5 Local Storage with saved integers and variables

I'm trying to achieve a function that makes the user able to save a mathematical formula that uses static variables that I've already created and save them with Local Storage.
Then the script fetches that formula from the Local Storage, does the math and displays the results on a table.
I have everything in order, except the fetching part;
as localStorage.getItem() returns a string, and converting it with parseFloat()/parseInt() only returns the first integer or NaN.
Both of this messes up the expected the results.
Is there any way I can get Objects from localStoage that contains both integers and variables?
Heres an example of a formula that should work, fetched by 5 localStorage.getItem() requests.
avgFrags*250
avgDmg*(10/(avgTier+2))*(0.23+2*avgTier/100)
avgSpots*150
log(avgCap+1,1.732)*150
avgDef*150
Any ideas or alternatives?
EDIT:
Each line represents the output of a getItem() request;
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
form_spot = localStorage.getItem('formula_spot');
form_cap = localStorage.getItem('formula_cap');
form_def = localStorage.getItem('formula_def');
localStorage store in a key-value store where every value is pushed to a string. If you are certent that you are handling "integers" you can push the string to a number:
var avgFrags = +localStorage.getItem('avgFrags'); // The + infront pushes the string to number.
I'm not completely sure that I understand your question.
(+"123") === 123
You can convert easily convert your strings to functions if you know the variable names before hand using Function(). The first parameter(s) are your function arguments and the last is your function body.
var func1 = Function('avgFrags', 'return avgFrags * 250;');
This is equivalent to:
function func1(avgFrags) {
return avgFrags * 250;
}
Known Function Signature
If you know what variable names will be used for each item in local storage then it should be easy for you to do what you want with function:
// from your edited question
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
// ... create functions
var fragsFunc = Function('avgFrags', form_frg );
var dmgFunc = Function('avgDmg', 'avgTier', form_dmg );
// ... get frags
var frags = fragsFunc (10); // frags = 2500; // if sample in storage
Unknown Function Signature
Now if you have a limited amount of variable names and you don't know which ones will be used with each function then you can do something like:
var avgFrags, avgDamage, avgTier, avgSpots, avgCap, avgDef;
// ... get from storage
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
// ... create functions
var fragsFunc = Function('avgFrags', 'avgDamage', 'avgTier', 'avgSpots', 'avgCap', 'avgDef', form_frag);
var dmgFunc = Function('avgFrags', 'avgDamage', 'avgTier', 'avgSpots', 'avgCap', 'avgDef', form_frag);
// ... get frags, only the first argument is used, but we don't know that.
var frags = fragsFunc (avgFrags, avgDamage, avgTier, avgSpots, avgCap, avgDef); // frags = 2500; // if sample in storage
You can make this simpler by having just one variable passed into the function which is an object that holds all of the arguments that can be passed to the function. Just have to make sure that the function writer uses that object.
var settings = {
avgFrags: 10,
avgDamage: 50,
// ...
};
var fragsFunc = Function('s', 's.avgFrags * 250');
var frags = fragsFunc (settings);
Getting parts with an regex
I am assuming that the above will get the job done, that you don't really want an object with variable names and numbers and operators.
If you just need the variable names and numbers (and operators) you can use a regex for that.
([a-z_$][\w\d]*)|([0-9]*\.?[0-9]+)|([^\w\d\s])
You can use that to create an array with each part. Also each part is grouped so you know which is a variable name, which is a number, and which is an other (parenthesis or operator)
var re = /(\w[\w\d]*)|([0-9]*\.?[0-9]+)|([^\w\d\s])/g,
match,
results;
while ((match = re.exec(localStorage.getItem('formula_frag'))) {
results.push({
text: match[0],
type: (match[1]) ? 'var' | (match[2]) ? 'number' : 'other'
})
}
You can view the output of the regex with your sample data using REY.
Yes you can set Objects in localstorage
Here is the fiddle for that - http://jsfiddle.net/sahilbatla/2z0dq6o3/
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObject = function(key) {
var value = this.getItem(key);
return value && JSON.parse(value);
}
$(function() {
localStorage.setObject('x', {1: 2, 2: "s"})
console.log(localStorage.getObject('x'));
});

Categories