How to use the value of a variable to define an object key?

Asked

Viewed 206 times

1

I wanted to return a Mongodb JSON with some filters, the problem is, when I try to pass a variable through the function, it doesn’t work, this is the code:

async find(req, res) {
    const { filter, input } = req.body;
    console.log(filter);
    console.log(input);
    const clients = await Client.find({ filter : { '$regex' : input, '$options' : 'i' } });
    console.log(clients);
    return res.json(clients);
},

The console logs stay:

name
testinput
[]

If I change:

const clients = await Client.find({ filter : { '$regex' : input, '$options' : 'i' } });

for:

const clients = await Client.find({ 'name' : { '$regex' : input, '$options' : 'i' } });

It works, but why can’t I pass a variable? I need to search with several different filters

  • Is it native lib or Mongoose? Do the following test to see what happens, set this way the search const filter = {name: {'$regex' : input, '$options' : 'i' }} and Client.find(filter) also test this way const filter2= {'$regex' : input, '$options' : 'i' } and Client.find({name: filter2}). Return with feedback.

  • THANKS for trying to help me Using on front: const Response = await api.post(/client/find, { "filter": this.state.filterSelected, "input": this.state.textFind });

No back:
https://hastebin.com/yoyoruxaki.coffeescript

Retornou isso:
https://hastebin.com/futixeletu.rb

  • So it was a mistake Identifier 'filter' has already been declared you have declared twice filter, rename it to something like filter3 and place await in the client’s frent.find on both attempts.

  • Thus? https://hastebin.com/tasatasife.coffeescript Printou isso: (Node:5429) Deprecationwarning: Collection.findAndModify is deprecated. Use findOneAndUpdate, findOneAndReplace or findOneAndDelete Instead. { name: { '$regex': ', '$options': 'i' } } { '$regex': ', '$options': 'i' } But where does the filter come in? If I do 'name' as a filter, it works,if I put a variable, it doesn’t work, it doesn’t make sense, even passing 'name' through the variable parameter as I showed above It works: const clients = await Client.find({ 'name' : { '$regex' : input, '$options' : 'i' } });

  • Yes, the client doesn’t understand it here await Client.find({ filter : { '$regex' : input, '$options' : 'i' } }); Because you’re talking like this, hey get for me all the filter with the following rule, but filter is not a database field but a variable with unknown values for find, the nome is a database field that will be searching with a specific rule. Well you must be using Mongoose then take a look at here.

  • I wanted you to test what I gave you to see if inserting the filter variable with the search field and the rule, to see if it would return the possible results, in this example filter = {name: {'$regex' : input, '$options' : 'i' }} is passing to find the search field and the search rule and inserting the filter directly into find await Client.find(filter), it would be as if the filter had come via body for direct insertion in find, I do something similar in my projects.

Show 1 more comment

1 answer

1


In Javascript itself, an object can be created in two ways:

// Forma 1
let obj1 = { name: "Fulano", age: 37 };

// Forma 2
let obj2 = { "name": "Fulano", "age": 37 };

That is, the key can be set with quotation marks, or without quotation marks.

In view of this, when you pass as argument the object:

{ filter : { '$regex' : input, '$options' : 'i' } }

You’re passing an object that has the key filter, yeah, that kind of key definition is accepted. However, as the input is being passed as a value, and not as a key, Javascript considers that you are using a variable.

Therefore, a way for you to use the value of a variable as the key of an object would be to use JSON.parse to convert a string in an object, like this:

let jsonObject = JSON.parse(`{ "${filter}" : { "$regex" : "${input}", "$options" : "i" } }`);

const clients = await Client.find(jsonObject);

Another way (even simpler) - and already this based on the definitions of ES6 - would be to use the definition of a key through the value returned by an expression, thus:

const clients = await Client.find({
    [filter]: {
        "$regex": input,
        "$options": "i"
    }
});

That is, there in [filter], a key with the variable value will be defined filter.

And when you say "expression", can even think of concatenation expressions of strings, for example:

{
    [filter]: {
        ['$' + 'regex']: input,
        "$options": "i"
    }
}

That is, the resulting key of ['$' + 'regex'] will be "$regex".

This form can become more interesting, as it ends up leaving the code, in a certain way, more "clean", and does not require it to use an additional functionality that is now shown "unnecessary".

However, note that to use this feature on the side of front-end, it may become necessary to implement some tools, such as Babel, for compatibility with older browsers (i.e., browsers that do not "support" ES6).

I hope I’ve helped!

  • I understood, but I’m not sure that’s it, because it didn’t work, it gave errors here: https://hastebin.com/ilulupodob.cs

  • Instead of the simple quotes ('), use double quotes ("). I had forgotten that the JSON.parse only converts strings that have keys set with double quotes. Sorry...

  • I edited the answer, putting the correct form...

  • That’s right, thank you very much!

Browser other questions tagged

You are not signed in. Login or sign up in order to post.