locked
Create custom json in javascript RRS feed

  • Question

  • User1856468055 posted

    I have a incoming json as:

    {
    "stage1":{
      "john":{
        "control": "1",
        "available": "true",  
        "comment": "n1",
        "value": "v1"
      },
      "Peter":{        
         "control":"2",
         "available":"true",
         "comment":"n2",
         "value":"v2",
         "userOptions": [
           {
            "text": "Utah",
            "value": "UT"    
           },
           {
            "text": "New York",
            "value": "NY"
           }
          ]
      }
     },
    "stage2":{
     "Abby":{
        "control": "3",
        "available": "false",  
        "comment": "n3",
        "value": "v3"
      },
      "Steven":{
         "required":"true",
         "control":"4",
         "comment":"n4",
         "value":"v4",
         "userOptions": [
           {
            "text": "New Jersey",
            "value": "NJ"    
           },
           {
            "text": "New York",
            "value": "NY"
           }
          ]
      }
     }
    }

    I want to parse the above JSON and create the following JSON:

    {
    "master1":{
          "stage1":{
             "John":{
                "control":"1",
                "value":"v1",
                "comment":"n1",
                "features":{
                   "available":"true"
                }
             },
             "Peter":{
                "control":"2",
                "value":"v2",
                "comment":"n2",
                "features":{
                   "available":"true",
                   "userOptions":{
                      "Utah":"UT",
                      "New York":"NY"
                   }
                }
             }
          },
          "stage2":{
             "Abby":{
                "control":"3",
                "value":"v3",
                "comment":"n3",
                "features":{
                   "available":"false"
                }
             },
             "Steven":{
                "control":"4",
                "value":"v4",
                "comment":"n4",
                "features":{
                   "userOptions":{
                      "New Jersey":"NJ",
                      "New York":"NY"
                   }
                }
             }
          }
      }
    }

    Could anyone help please

    Friday, July 5, 2019 1:33 PM

All replies

  • User753101303 posted

    Hi,

    As far as I can see it seems the incoming object just become the "master1" property of the output object ?

    If working with an actual object it should be :

    var outputObject={ master1:inputObject };

    If working with a string it seems you should just append 2 lines at the top/bottom of your existing string. If it doesn't help please be more explicit about the problem you have in doing that...

    Friday, July 5, 2019 1:46 PM
  • User475983607 posted

    This is a pretty simple but tedious task . If we assume the JSON shown is a type and not a string then it is a simple matter of building the new object model and assigning values form the incoming type to the wanted type. 

    However, the input is not formatted properly.  Properties like John and Peter are dynamic and should have the format similar to the following.

    {
    "stage1":{
    	"person" {
    		"name" : "John"
    		"control": "1",
    		"available": "true",  
    		"comment": "n1",
    		"value": "v1"
      }
     }
    }

    Can you show the code that you have tried?

    Friday, July 5, 2019 1:50 PM
  • User1856468055 posted

    Earlier I had input as below:

    {
      "name": "John",
      "control": "1",
      "available": "true",  
      "comment": "n1",
      "value": "v1"
     },
     {
      "name": "Peter",  
      "control": "2",
      "available": "true",    
      "comment": "n2",
      "value": "v2",
       "userOptions": [
       {
        "text": "Utah",
        "value": "UT"    
       },
       {
        "text": "New York",
        "value": "NY"
       }
      ]
     }

    And I used the below code:

    let res = input.reduce((acc, user) =>
    {
        let {name, available, userOptions, ...others} = user;
        acc[name] = {...others, features: {available: JSON.parse(available)}};
    
        if (userOptions !== undefined)
        {
            acc[name].features.userOptions = {};
    
            userOptions.forEach(({text, value}) =>
            {
                acc[name].features.userOptions[text] = value;
            });
        }
    
        return acc;
    }, {});
    
    console.log(res);

    But then I wanted the output as:

    {
      "John": {
        "control": "1",
        "comment": "n1",
        "value": "v1",
        "features": {
          "available": true
        }
      },
      "Peter": {
        "control": "2",    
        "comment": "n2",
        "value": "v2",
        "features": {
          "available": true,
          "userOptions": {
            "Utah": "UT",
            "New York": "NY"
          }
        }
      }
    }

    While the above worked, now my input has changed as per my original post.  The new input has little more nested objects which I am not sure how to proceed.

    Regarding "master1" I just want to add that to my object at top once I create final json. "master1" is not a part of original input.

    Friday, July 5, 2019 2:00 PM
  • User475983607 posted

    You need to fix the object model design.  The current design makes John and Peter different objects which does not make sense.

    Friday, July 5, 2019 2:15 PM
  • User1856468055 posted

    My input is nested as below:

    {  
       "stage1":{  
          "John":{  
              //some data
          },
          "Peter":{  
              //some data
          }
       },
       "stage2":{  
          "Abby":{  
              //some data
          },
          "Steven":{  
              //some data
          }
       }
    }

    So I can have stage1, stage2, stage3 and so on.
    Under each stage I have more objects like under stage1 I have John, Peter and can be more. Same goes for stage2.
    Not sure whats missing here.

    Friday, July 5, 2019 2:32 PM
  • User475983607 posted

    It a poor design.  As stated above, Perter, John, Abby, and Steven are all different nested objects.  The design makes querying the results very difficult which is the main issue you are currently facing.  

    I recommend fixing the object model to make it easier to loop over the result set.  Otherwise, you'll need to use an indexes.

    {
    "stage1":{
    		"person": {
    			"name" : "John"
    			"control": "1", 
    			"comment": "n1",
    			"value": "v1",
    			"features":{
                   "available":"true"
                }
    		}
    	}
    }

    Friday, July 5, 2019 3:01 PM
  • User1856468055 posted

    Actually these objects are created after user selection (from a UI table). Once user selection is made I want to then create the final json and send it over to my api to save.

    So basically the names peter, john etc are all tabs and within each tab there is a UI table. 

    Have to see how I can change my input.

    Friday, July 5, 2019 3:10 PM
  • User475983607 posted

    Actually these objects are created after user selection (from a UI table). Once user selection is made I want to then create the final json and send it over to my api to save.

    So basically the names peter, john etc are all tabs and within each tab there is a UI table. 

    Have to see how I can change my input.

    I don't get the design or the reasoning.  If you want to drill into Peter then you need to know there is a "Peter" property.

    input.stage1.Peter

    A  better approach is...

    input.stage1.User

    IMHO, stage1 and stage2 are also an issue.  I would have a stage type and move the  1, 2, or 3 into a property of stage.

    Friday, July 5, 2019 3:31 PM
  • User753101303 posted

    The input you had earlier is actually better. And so you do have control as well on the input object ? If yes, why would you want to transform that rather than using all along a structure that makes sense ?

    Friday, July 5, 2019 3:43 PM
  • User1856468055 posted

    Patrice earlier we did not had any tabs, just one HTML table (with user input) where user was entering data. Now with multiple tabs it made things complex. 

    So now with multiple tabs we would have HTML table within each tab.

    So Stage 1 is one tabe with John & peter 2 separate rows of the table. The rest of the data is associated with each of its row.
    Stage 2 is second tab with Abby & Steven rows of this table.

    Friday, July 5, 2019 5:14 PM
  • User753101303 posted

    I would use a top level object having a property being an array of tabs and each tab having a property being an array of persons. Moving "data" to "programming elements" ie a user name to the name of a property or for a database a year to a table name is often if not always a bad idea.

    Friday, July 5, 2019 6:08 PM
  • User475983607 posted

    CsharpAsp.net

    Patrice earlier we did not had any tabs, just one HTML table (with user input) where user was entering data. Now with multiple tabs it made things complex. 

    So now with multiple tabs we would have HTML table within each tab.

    So Stage 1 is one tabe with John & peter 2 separate rows of the table. The rest of the data is associated with each of its row.
    Stage 2 is second tab with Abby & Steven rows of this table.

    Your explanation of why the object model got to this point does not change the fact that the model design is poor and should be fixed.  Your life will be much easier.   

    Otherwise, you 'll end up with a complex solution that involves fetching an array of keys (John, Peter, etc).

    var nameKeys = Object.keys(input.stage1);

    This results is an array that contains the dynamic properties.  You can use array of keys to programmatically get to the John and Peter objects with out having to know about the types.

    ["john", "Peter"]

    The same type of issue applies to stage1 and stage2.


      

    Friday, July 5, 2019 6:22 PM