Mahesh Mahesh - 6 months ago 96
Node.js Question

Nodejs API - multer fileupload - Adding property and its value dynamically to JSON object

In my user interface (angularjs) I create new row. Each row have file upload button. I want to upload all files together with metadata and save each row in one call. The complex object which I post to Nodejs API is somewhat like below

var activity = {
"Id" : 1,
"Name" : "Test",
"Steps" : [
"FileUrl": {fileObject} // this property if bound with the file upload directive 'ng-file-upload' by Daniel Farid
"Description" : "Save this file"
"FileUrl": {fileObject} // this property if bound with the file upload directive 'ng-file-upload' by Daniel Farid
"Description" : "Save this file2"

This JSON will be posted to Node js API. On Nodejs side I am using multer to save the uploaded files to server. I get all the files in API using multer's .any() method, but I get the posted object without Steps[x].FileUrl property.

The file object that has the information about the field name in which this file was added. Below is the info I see in debugger.


Now what I want to do it, since My complex object that is posted does not have Steps[0].FileUrl property, I want to iterate for each file (i.e. req.files) and use fieldname to create this property and assign the originalName as value to it.

How I am trying to do it

var deployment = req.body;
var app = _config.getApplicationConfig(req.body.ApplicationId);

//Move file to the deployment folder.
var newPath = _utils.DetermineFileName(f.originalname, app.packageDir);
_fs.renameSync(f.path, path.join(app.packageDir,newPath));
var newFileName = path.basename(newPath);
//set the file url to corresponding field
var evalExp = "deployment." + f.fieldname; //I get evalExpression as "deployment.Steps[0][FileUrl]"
eval(evalExp); //Here it fails saying FileUrl is not defined
evalExp = "deployment." + f.fieldname + "= \"" + newFileName.toString() + "\"";

Does anyone know how can as assign the property to an object at run time?


I have found solution to this as below I have wrote a function that converts the [] notation to . notation ie. myobj[myprop] to myobj.myprop

var convertToDotNotation = function (keyPath) {
    var bracketSyntaxRegex = new RegExp(/\[([^0-9])\w+\]/g); //matches the javascript property defined in [] syntax but not an array 
    var matches = keyPath.match(bracketSyntaxRegex)
    if(matches && matches.length > 0){
            //replace '[' with '.' and ']' with emptyspace
            var dotSyntax = p.replace("[",".").replace("]","");
            keyPath = keyPath.replace(p,dotSyntax);
    return keyPath;

This will give me the '.' notation which can dynamically create the property and set the value

var newFileName = "MyFile.pdf";
var evalExp = "deployment[0].[FileUrl]" ;
var temp = convertToDotNotation(evalExp);
eval(temp + "= \"" +  newFileName + "\""); 

Hope it helps someone.