0

I'm really not sure how to word this question, which is why I've had some trouble googling it, but I'm trying to make, basically, a helper function for modifying mongoDB data, and I have a list of commands, in this format:

              var commands = {
                    "find": {
                        "names": {
                            "find":["query"],
                            "toArray":["callback"]
                        }
                    },
                    "sort": {
                        "names": {
                            "find":[],
                            "sort":["query"],
                            "toArray":["callback"]
                          }                          
                    },
                    "limit": {
                        "names": {
                            "find":[],
                            "limit":["number"],
                            "toArray":["callback"]
                          }                          
                    },
                    "deleteOne": {
                        "args":["query","callback"]
                    },
                    "findOne": {
                        "args":["query", "callback"]
                    },
                    "insertOne": {
                        "args":["query", "callback"]
                    },
                    "insertMany": {
                        "args":["array"]
                    },
                    "remove": {
                        "args":["query", "callback"]
                    },
                    "drop": {
                        "args":["callback"]
                    },
                    "updateOne": {
                        "args":["query", "newvalues", "callback"]
                    },
                    "aggregate": {
                        "args": ["query"],
                        "hasCB":"toArray"
                    },
                    "createCollection": {
                        "args":["string", "callback"]
                    }
                };

and then a dictionary of those values: and the idea is to call a particular mongoDB function based on the input, like

Based off of this, I am able to make an array that looks like this:

[["find",[]],["sort",[{"name":-1}]],["toArray",[/*some function reference*/]]],

and based on that, I want to call:

something.find().sort({"name":-1}).toArray(callback);

and if I have something like this:

[["find",[{"name":"hi"}]],["toArray",[/some function reference/]]],

I should be able to produce the result of: something.find({"name":"hi"}).toArray(cb);

all in the same function.

This isn't EXACTLY a node.js question, more of JavaScript in general, that given a function in the format of

[[functionName1,arrayOfArguments1],[functionName2,arrayOfArguments2],[functionName3,arrayOfArguments3]]

how do you call functionName1(...arrayOfArguments1)[functionName2](...arrayOfArguments2)[functionName3](...arrayOfArguments3),

using a loop, or one function ,lets say? Instead of manually writing it out, how do I produce this result? I'm currently doing it like this with a switch / case, but that's less than ideal:

switch(funcList.length) {
                        case 2:
                            console.log(col[funcList[0][0]](...funcList[0][1])[funcList[1][0]](...funcList[1][1]));
                            break;
                        case 3:
                            console.log(col[funcList[0][0]](...funcList[0][1])[funcList[1][0]](...funcList[1][1])[funcList[2][0]](...funcList[2][1]));
                            break;
                    }
  • Why is the nested data structure necessary? `["find","names","find","query","toArray", "callback"]` or `"find names find query toArray callback"` produce the same result. – guest271314 Feb 06 '19 at 05:26
  • See [Execute Promise tree consecutively from parent to child](https://stackoverflow.com/q/54083642/) – guest271314 Feb 06 '19 at 05:43

3 Answers3

0

You Just parse with Table Name

var Jstr = JSON.parse(commands).find;

Now, Jstr Contains

"names": {
     "find":["query"],
      "toArray":["callback"]
  }

Like this same, you can parse and get the value.

Elango Sengottaiyan
  • 166
  • 1
  • 2
  • 13
  • Hi thanks, I'm able to get the values fine, the problem is turning those values into a function call for the sub-functions. Each object in the array represents a different function call, so [["find",["query"]],["toArray", ["callback"]]] would result to: masterFunction["find"]("query")["toArray"]["callback"], see where I'm going with this? :) – B''H Bi'ezras -- Boruch Hashem Feb 06 '19 at 07:13
0

Let's say

const functionArr = [["find",[]],["sort",[{"name":-1}]],["toArray",[/*some function reference*/]]];

you can then write,

const functionChainResult = initialObj;
functionArr.forEach(fn => {
  functionChainResult = functionChainResult.apply(window[fn[0]], fn[1]);
});
console.log(functionChainResult);

For using some context other than window, you can see this.

Aakash Verma
  • 3,705
  • 5
  • 29
  • 66
  • Hi thanks, but I think I'm mis-explaining myself: I'm not simply trying to call an array of functions with their argument pairs, I can do that easily with arr.forEach(x=>functionDictionary(x[0])(...x[1]), the problem is that I'm trying to call SUB functions in a recursive manner, like lets say an object has a function: foo(arg).bar(other).foobar(int, str).execute(str), so each element of the array represents a different SUB function: [["foo",["asdf"]],["bar",["other"]],["foobar",[123,"hi"]],["execute",["today"]]] ??? How do I produce the function call from the array?? – B''H Bi'ezras -- Boruch Hashem Feb 06 '19 at 07:00
0

What I understand from your question is you want to call some sequence of functions based on an array which had set of the function name in strings. If I am right, I think this solution will help you.
Let's try to use 'apply' feature in a function.


var arrx = [["find",[]],["sort",[{"name":-1}]],["toArray",[x]]];

function callSequence(model, operationArray) {
  var res = model; // this will help to call function chain

  // recursive function
  function call(arr, index) {
    // arr[index][0] is current function name
    // arr[index][1] is current function arguments 
    res = res[arr[index][0]].apply({}, arr[index][1]);
    if(index < arr.length) {
      call(arr, index + 1); // call recursively throught the array.
    }
  }

  call(arrx, 0);
}

callSequence(Something, arrx);
Viran Malaka
  • 417
  • 4
  • 10
  • Hi thanks for the detailed code answer, but I'm actually not trying to simply call a sequence of individual functions; rather, each element in the array represents a different sub-function, so for example, this array: [["find",["query"]],["toArray", ["callback"]]] should produce this result: masterFunction["find"]("query")["toArray"]["callback"], I'm able to call the functions IF they were their own functions, simply with: arr.forEach(x=>functionDictionary(x[0])(...x[1]) – B''H Bi'ezras -- Boruch Hashem Feb 06 '19 at 07:15