Restructure JS object to fit binding MVC model - javascript

I have a javascript object with nested objects obtained by a plugin saved in a variable called 'json':
// var json:
Object {0: Object, 1: Object}
0: country
countryCapital: Object
ministers: Array[1]
1: country
countryCapital: Object
ministers: Array[3]
// Should be restructured to fit MVC models
World
Country Array [2]
Capital: Object
Minister: Array [1]
Because I'm sending the data using jQuery-ajax to a MVC controller I'm trying to rename/restructure them to bind them to a MVC Model so I can send the whole 'World' object as 1 parameter.
// Controller
[HttpPost]
public void Save(World world)
// Model structure:
World
* Country (list)
1 Capital
* Minister (list)
How do I convert the javascript object to the right structure that fits the Model parameter? Do I need to loop everything or can it be done in a better way?
UPDATE:
json object update, it's a lot of data so I simplified it.
// World
{
"0": { // Country
"ministers":
{
"objects": [
{
"name": "name1"
},
{
"name": "name2"
}
]
},
"countryCapital": {
"name": "...",
}
},
"1": { // Country
"ministers":
{
"objects": [
{
"name": "name1"
},
{
"name": "name2"
}
]
},
"countryCapital": {
"name": "...",
}
}
}

I suppose you're searching for $.map().
At the background it's looping your collection but it much cleaner to use it in your case.

Updated to use your example json. Jsfiddle
var world = {}
for (var countryIteration in originalObject) {
var country = originalObject[countryIteration];
world[countryIteration] = { //you need to this because you need dynamic keys.
capital : country.countryCapital.name,
ministers : country.ministers.objects
}
}

I found a working solution thanks to teo van kot using jQuery map.
var world = {}
$.map(json, function (value, i) {
if (i == "countryCapital") {
world.Capital = value
}
if (i == "ministers") {
world.Minister= value
$.each(value, function (j, minister) {
world.Minister[j].Name = minister.name;
delete minister.name;
});
}
}, world);

Related

Filter Array Using Partial String Match in Javascript

I have an array of objects where the value I need to filter on is buried in a long string. Array looks like:
{
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
},
So if I wanted to grab all the partnerId objects where value includes parent_sku how would I do that?
console.log(data.value.includes('parent_sku') returns cannot read property 'includes' of null.
EDIT:
Didn't think this mattered, but judging by responses, seems it does. Here's the full response object:
Response body: {
"data": {
"configurationByCode": [
{
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
}
I'm passing that into a re-usable function for filtering arrays:
const parentSkuPartners = filterArray(res.body.data.configurationByCode, 'parent_sku');
Function:
function filterArray(array, filterList) {
const newList = [];
for (let i = 0; i < array.length; i += 1) {
console.log('LOG', array[i].data.value.includes('parent_sku');
}
}
The problem is somewhere else. The code you've tried should work to find if a value contains a string – I've added it the snippet below and you'll see it works.
The issue is how you are accessing data and data.value. The error message clearly states that it believes that data.value is null. We would need to see the code around it to be able to figure out what the problem is. Try just logging to console the value of data before you run the includes function.
const data = {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}", "partnerId": 1
};
console.log('includes?', data.value.includes('parent_sku'));
You can use data.value.includes('parent_sku') as you have suggested. The issue here is that your object is nested inside an unnamed object.
try:
"data": {
"value": "{\"cols\":[\"parent_sku\"],\"label\":\"Style\",\"description\":\"Enter Style.\",\"placeholderText\":\"Style 10110120103\"}",
"partnerId": 1
}
The problem was some of the values for value were null. Adding an extra conditional fixed it:
if (array[i].data.value !== null) {
Use lodash includes, and lodash filter like
let configurationByCode = [{
data: {
value: {
cols:["parent_sku"],
label:"Style",
description:"Enter Style.",
placeholderText:"Style 10110120103"
},
"partnerId": 1
}
}, {
data: {
value: {
cols:["nothing"],
label:"Style",
description:"Enter Style.",
placeholderText:"Style 10110120103"
},
"partnerId": 2
}
}];
let wantedData = _.filter(configurationByCode, (config) => {
return _.includes(config.data.value.cols, 'parent_sku');
});
console.log( wantedData );
https://jsfiddle.net/76cndsp2/

MongoDB using parameter for nested location

have a little newbe problem although I couldn't find a solution for similar problems, that worked for me.
Here is my collection:
{
"_id": ObjectId("5bc712851224ceec702d9bdf"),
"index": "123456",
"name": "Jan",
"surname": "Nowak",
"grades": {
"IABD": [
2,
3.5,
4
],
"NPAD": [
4,
4,
5
]
}
}
now I need to push additional grades to specific (function parameters) courses.
So I tried tackling it on a few levels and I'd love somebody to walk me through it according to this:
First I wanted to succeed not passing course as a parameter:
function add_grade(index="123456", course="IABD", grade=5.5)
{
db.students.update( {"index" : index }, { $push: { "grades" : { "IABD" : grade } } } );
}
well nothing happened (grade was not added to the list of grades)
I wanted to see some result, so I wanted to see if $set would work and it did!
function add_grade(index="123456", course="IABD", grade=5.5)
{
db.students.update( {"index" : index }, { $set: { "grades" : { "IABD" : grade } } } );
}
but it threw away my entire grades object (as expected). At least I know I'm on the right track.
Question 1: Why $push didn't work the way I expected
Question 2: how to use course parameter in set/push?
Just to clarify Q2, I'm not lazy, I've tried many approaches, none of which worked, please help!
You can try below query. That push 6 into IABD
db.getCollection('students').update( { "index": "123456" }, { $push: { "grades.IABD" : 6 } });
$push is not working the way you are expecting because the array field is in an embedded document and to push you need to use
dot notation i.e. instead of
{ "$push": { "grades" : { "IABD" : grade } } }
what you need is to specify the field as dot notation
{ "$push": { "grades.IABD" : grade } }
To use the course parameter in push you would want to create an update object that holds the dot notation
{ "grades.<course>" : grade }
for example
var course = "IABD";
var grade = 5.5;
var update = {};
update["grades." + course] = grade;
printjson(update) // prints { "grades.IABD" : 5.5 }
So your function will look like
function add_grade(index="123456", course="IABD", grade=5.5) {
var update = {};
update["grades." + course] = grade;
db.students.update(
{ "index" : index },
{ "$push": update }
);
}

Polymer JS reading from JSON file

I'm trying to read a sub-array from a JSON file in Polymer in JS and return the sub-array to be used in a dom-repeat. However, it tells me that the sub-array is undefined. I tried re-structuring the JSON file in various ways but no luck. I think I'm not using the right syntax somewhere.
Right now the JSON looks like this:
{
"url": "dn8",
"volpage": "DN iii 1",
"languages": [{
"pt": {
"authors": ["Laera"],
"titlelan": "Title in Portuguese"
},
"fr": {
"authors": ["Moi"],
"titlelan": "Title in French"
},
"es": {
"authors": ["Jesus"]
}
}]
}
I'm trying to get a sub-array called languageData which just hold the specific data for an input-language. The input has the correct value for the inputLanguage, like for instance "pt". My JS looks like this:
Polymer({
is: 'test-data',
properties: {
inputUrl: String,
inputLanguage: String,
inputData: {
type: Array,
notify: true,
value: function(){return []}
},
languageData: {
type: Array,
computed: '_computeLanguage(inputData,inputLanguage)'
}
},
_computeLanguage: function(inputData,inputLanguage) {
var lanarray = inputData.languages[inputLanguage];
return lanarray ? lanarray : "";
}
});
Any help is very much appreciated!
As you can see the languages property of your JSON is not an Object but and Array.
Your "Polymer code" works well, the problem is that you are trying to get the languageData as if it were an Array:
var lanarray = inputData.languages[inputLanguage];
Actually, languages contains an array of objects and you can't find your lang object in this way.
A possible solution could be:
var lanarray = inputData.languages[0][inputLanguage];

Create Javascript objects from a template

I want to create a javascript object from a template. The problem is I don't know what the template is going to look like beforehand. As a simple example, if I had the template function
template = function (data) {
return {
title: data.title
}
}
then I could run template({ title: "Steve" }) and get back the object
{ title: "Steve" }
Because data.title is not evaluated until I call the template function. But I'm constructing an object based on user input where the field names are not known beforehand and could be deeply nested anywhere in the object.
If I define the object that is returned beforehand then the data.title field in the example would already be evaluated and wouldn't use the input data. For example, I want to be able to define the template object like
obj = { title: this.title }
then redefine the template as
template = function () {
return obj
}
and call template.call({title:"Steve"}). But currently I get back
{ title: undefined }
because this.title was already evaluated when I defined obj. Maybe I'm approaching this the wrong way, because I keep coming to the conclusion that I'd have to modify the function by stringifying it, modifying the string to include the unevaluated code this.title and creating a new function from the string. But that seems like a plain awful idea.
And traversing the object looking for special values to replace seems expensive and complicated. I also looked for some sort of javascript object templating library but didn't find anything.
EDIT: To make it more clear that the input data and the template structure won't necessarily match, I may want have a template that looks like
template = function (data) {
return {
name: "Alfred",
stats: {
age: 32,
position: {
level: 10,
title: data.title
}
}
}
}
and call template({title:"Manager"}) to get
{
"name": "Alfred",
"stats": {
"age": 32,
"position": {
"level": 10,
"title": "Manager"
}
}
}
So I've managed to solve this by (ab)using functions as metadata to mark the values that should be replaced in the template. This is made possible by two things:
I only need valid JSON values, so I can safely say that functions aren't literal user input
JSON.stringify has a replacer parameter which will traverse the object and can be used to pass the input data to the template
Using a template generator like this
var templateMaker = function (object) {
return function (context) {
var replacer = function (key, val) {
if (typeof val === 'function') {
return context[val()]
}
return val;
}
return JSON.parse(JSON.stringify(obj, replacer))
}
}
I create a template object, replacing field names with functions that return the field name
var obj = {
name: "Alfred",
stats: {
age: 32,
position: {
title: function () { return 'title' },
level: function () { return 'level' }
}
}
}
then I create the template function, define my input, and render it to an object
var template = templateMaker(obj);
var data = {
title: "Manager",
level: 10
}
var rendered = template(data);
and magically, the object output looks like
{
"name": "Alfred",
"stats": {
"age": 32,
"position": {
"title": "Manager",
"level": 10
}
}
}
Maybe template engines like Mustache would help you with this.
You can define your object template in string:
var template = '{ title: {{title}} }';
then render it with the data, and convert it to json:
var data = {title: 'I am title'};
var obj = JSON.parse(Mustache.render(template, data));
UPDATE:
I read your updated example, here is the corresponding example:
var template = JSON.stringify({
name: "Alfred",
stats: {
age: 32,
position: {
level: 10,
title: '{{title}}'
}
}
});
var data = {title: 'I am title'};
var obj = JSON.parse(Mustache.render(template, data));
obj.stats.position.title == "I am title";

How can i build this json format in javascript?

I have this json where the values will be passed dynamically in javascript,
{
"User": {
"-xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
"memNum": "70000211981",
"orderslist": [
{
"orderid": "5119534",
"ordersource": "ONLINE",
"transactiondttm": "2014-01-09"
},
{
"orderid": "5119534",
"ordersource": "STORE",
"transactiondttm": "2014-01-09"
}
]
}
}
and i tried using this function to build the json but it doesnt seem to work,
function addOrder(req, orderId, orderSource, transactiondtm) {
req.User.orderslist.orderid.push(orderId);
req.User.orderslist.ordersource.push(orderSource);
req.User.orderslist.transactiondtm.push(transactiondtm);
}
Any suggestion..
The elements of orderslist are objects, not arrays, so you can't push onto them. You have to build them as objects, and then push that onto the orderslist array.
function addOrder(req, orderId, orderSource, transactiondtm) {
req.User.orderslist.push({ orderid: orderId,
ordersource: orderSource,
transactiondtm: transactiondtm });
}
Something like this should work.
function addOrder(req, orderId, orderSource, transactiondtm) {
req.User.orderslist.push({
"orderid": orderId,
"ordersource": orderSource,
"transactiondtm": transactiondtm
});
}
Javascript objects can be acessed like an array.
That way you can create dinamic members.
user = {"orderList":[]};
for(var i = 0; i<5; i++){
user.orderList[i] = {};
user.orderList[i]["orderId"] = i;
user.orderList[i]["orderSource"] = "STORE";
}
alert(user.orderList[0].orderSource);
//Shows "STORE"
you can see the code working here http://jsfiddle.net/wmgE6/

Categories

Resources