'How can I use this React component to collect form data?

I've created two components which together create a 'progressive' style input form. The reason I've chosen this method is because the questions could change text or change order and so are being pulled into the component from an array stored in a JS file called CustomerFeedback.

So far I've been trying to add a data handler function which will be triggered when the user clicks on the 'Proceed' button. The function should collect all of the answers from all of the rendered questions and store them in an array called RawInputData. I've managed to get this to work in a hard coded version of SurveyForm using the code shown below but I've not found a way to make it dynamic enough to use alongside a SurveyQuestion component. Can anybody help me make the dataHander function collect data dynamically?



Solution 1:[1]

You can not inject string in to query, but you can pass an object in query, prepare an array of objects and use it in query,

For understanding i have updated your method as below, you can change it as per your requirement,

const createCarFetchquery = (company, model, minPrice, maxPrice) => {
    
    let query = [];
    if (company) query.push(getQuery('$eq', 'company', company));
    if (model) query.push(getQuery('$eq', 'model', model));
    if (minPrice) query.push(getQuery('$gte', 'minPrice', minPrice));
    if (maxPrice) query.push(getQuery('$eq', 'maxPrice', maxPrice));

    if (query.length) return { $or: query };
    return {};

}

const getQuery = (opertor, key, value) => {
    return { [key]: { [opertor]: value } };
};

console.log(createCarFetchquery("ABC", "A", 10, 12));

and use it in your query, but make sure you have wrapped your query by async/await method,

let carsPromise = await Car.find(
   carsFetchQuery(company, model, minPrice, maxPrice)
)
.skip(offSet)
.limit(rowsPerPage)
.lean();

Solution 2:[2]

find requires a JSON object, thus it may work with

let carsPromise = Car.find(
   JSON.parse(carsFetchQuery(company, model, minPrice, maxPrice))
)

That's highly vulnerable for NoSQL injection.

A better approach would be like this one:

var query = []

var field = {}
field['company'] = {}
field['company']['$eq'] = company
query.push(field)

var field = {}
field['minPrice'] = {}
field['minPrice']['$gte'] = minPrice
query.push(field)

// or a  bit shorter (thanks to turivishal) 
query.push({ ['maxPrice']: { ['$eq']: maxPrice} })

let carsPromise = Car.find({$and: [ { $or: query } ] })

You an simply push as many conditions as you like with a loop. However, it is still possible to inject NoSQL code, for example when the URL looks like this:

...?model['$ne']=null

then the query would return all documents where model is not null - most likely all, see https://blog.websecurify.com/2014/08/hacking-nodejs-and-mongodb.html

Thus you should protect input values with mongo-sanitize or similar:

field['company']['$eq'] = sanitize(company)

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 turivishal
Solution 2