0

I will start by saying I do know how to use the javascript JSON library, my question is not as simple as that, so please do read the detail not just the title, as I couldn't express it well in the title...

What I am trying to achieve is converting a csv to a JSON document but using a dynamic schema to map the varying schemas of the csv's to a defined document schema

I have a JSON document that has string keys i,e "Field1", "Field2", etc.... the corresponding value is a pipe delimited string that contains the type of document before the first delimiter and then each string within the delimiters builds up a "Path" of the dynamic json document I want to create...

So the csv comes in and is converted to json....

"Field1" in the uploaded CSV contains the value "Potatoes"

We retrieve the pipe delimited string for "Field1" which has the value "1|Vegetables|RootVeg"

Therefore dynamically I need to build the json document up so that for this field the corresponding document section would look like

{ "Vegetables" : { "RootVeg" : "Potatoes"} }

Hopefully that makes sense.... Below is the various foreach loops I am trying to build this up with....

                var vesselprimary = [];
                var vesselsecondary = [];
                angular.forEach(value, function (value2, key2) {
                    var pipedValue = data[0][key2];
                    console.log("pipedvalue", pipedValue);
                    console.log("value2", value2);
                    var arrayValues = pipedValue.split("|");
                    if (arrayValues[0] === 1) {
                        //Create the VesselPrimary JSON object to put into the body of the post

                        if (arrayValues.count > 2) {
                            vesselprimary[arrayValues[1]] = {};
                            vesselprimary[arrayValues[1]][arrayValues[2]] = value2;
                        } else {
                            vesselprimary[arrayValues[1]] = value2;

                        }
                    } else {
                        //Create the VesselSecondary JSON object to put into the body of the post
                        if (arrayValues.count > 2) {
                            vesselsecondary[arrayValues[1]] = {};
                            vesselsecondary[arrayValues[1]][arrayValues[2]] = value2;
                        } else {
                            vesselsecondary[arrayValues[1]] = value2;

                        }
                    }

                });
                //console.log(vesselprimary);
                this.push(vesselprimary);
            }, jsonArr);

But my output is a less than impressive....

"[[],[],[],[],[],[],[],[],[]]"
2
  • The danger here is that the are so many pitfalls in reading CSV's. Your final code will likely work for most scenarios but what about a CSV with this ... "val1", "val2, val2b", "val3" - if possible use a JavaScript CSV reader instead of doing this manually - if you are using NodeJS ... npmjs.com/package/csv ... if not then look for a JS lib out there that does the work for you - maybe this is not the answer you want but you should challenge your approach Commented Dec 11, 2015 at 17:08
  • Hi @danday Thanks for your comment and it's a totally valid point, however this part is actually not regarding a csv import, that I will probably do with a library of some sort, this is reading a configuration (read schema) json file that is telling the system how to translate the output of the csv library into my DocumentDB JSON format...., does that make sense? Commented Dec 14, 2015 at 9:46

1 Answer 1

0

In the end it appeared that the best way to do it was to actually build it up as a string and then use a 3rd party to convert it to JSON... not sure that this is the best practice way of doing it but it seems to be relatively efficient... obviously I would be interested to hear of an alternative approach as building up strings always seems like the last ditch effort to me!!

var csvObj = JSON.parse(json);
angular.forEach(csvObj, function(value, key2) {

var actualJsonPrimary = {};
var actualJsonSecondary = {};
var jsonStrPrim = "{";
var jsonStrSec = "{";
angular.forEach(value, function(value2, key2) {
       var pipedValue = data.data[0][key2];
       var arrayValues = pipedValue.split("|");
       if (arrayValues[0] === "") return;
       if (arrayValues[0] === "1") {
       if (arrayValues.length > 2) {
          jsonStrPrim += " '"
          + arrayValues[1].toString() + "' :  { '"
          + arrayValues[2].toString() + "' : "
          + "'" + value2 + "'" + " },";
              } else {
              jsonStrPrim += " '"
              + arrayValues[1].toString() + "' : "
              + "'" + value2 + "'"
              + " ,";
          }
        } else {
            if (arrayValues.length > 2) {
               jsonStrSec += " '"
               + arrayValues[1].toString() + "' :  { '"
               + arrayValues[2].toString() + "' : "
               + "'" + value2 + "'"
               + " },";
            } else {
               jsonStrSec += " '"
               + arrayValues[1].toString() + "' : "
               + "'" + value2 + "'"
               + " ,";
               }
            }
         });
         jsonStrPrim += "}";
         jsonStrSec += "}";
         actualJsonPrimary = eval("(" + jsonStrPrim + ")");
         actualJsonSecondary = eval("(" + jsonStrSec + ")");
         $http.post('http://myurl/api/sausages',
         JSON.stringify(actualJsonPrimary),
         {
              headers: {
               'Content-Type': 'application/json'
              }
         }
         ).then(function(data) {
             deferredObject.resolve(data.data);

         },
          function(err) {
              console.log("Error posting to API", err);
         });
       });

Sorry about the dodgy format but hopefully this might give someone an idea of how to do it better!!

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.