0

I have an html/handlebars form set up with a Node/Express backend. the form offers options populated from a database. I am able to get the form to return a single user selected value and save it to my mongodb, but I really need the whole object.

{{#each proxyObj}}
            <p>
                <label>
                    <input type="radio" name="proxyTitle" value="{{title}}"/>
                    <span>{{title}}</span>
                </label>
            </p>
            {{/each}}

and this is the express:

router.post("/proxies/:id", ensureAuthenticated, (req, res) => {
  Project.findOne({
       _id: req.params.id
    }).then(project => {
    const newProxy = {
        proxyTitle: req.body.proxyTitle
        // I need the other object values to go here, or to be able to retrieve them later
   };
    // Add to proxy array on the Project object in the collection
    project.proxies.push(newProxy);

    project.save().then(project => {
    res.redirect(`/projects/stakeholders/${project.id}`);
    });
  });
});

Is it more sensible to try to load in the entire object as a value in the input field, or to return the id of the object, and look it up in the db? I need to display some of the returned object information on the same page, and also to use it later. Which is more efficient, and what is the best way to achieve it?

Maksym Fedorov
  • 6,383
  • 2
  • 11
  • 31
bevc
  • 203
  • 3
  • 14

1 Answers1

0

If I'm getting it right, the problem is that you're trying to put multiple inputs with the same name on one form in <input type="radio" name="proxyTitle" value="{{title}}"/>, which gives you something like

<input type="radio" name="proxyTitle" value="Title 1"/>
<input type="radio" name="proxyTitle" value="Title 2"/>
<input type="radio" name="proxyTitle" value="Title 3"/>

As explained here, the browsers will chew it, but the server-side handling may require some adjustments.

In your case, the easiest fix would be to add index to the names of parameters. So, your form would be looking like this:

{{#each proxyObj}}
    <p>
        <label>
            <input type="radio" name="proxies[{{@key}}]" value="{{this}}"/>
            <span>{{this}}</span>
        </label>
    </p>
{{/each}}    

(note that if proxyObj is an array, you would have to use @index instead of @key; also, depending on the proxyObj fields' structure, you may have to use this.title as the values to display and whatnot).

As for your server-side handling, you'll have to loop through the proxies you receive and handle them one by one, e.g.

  router.post("/proxies/:id", ensureAuthenticated, (req, res) => {
    Project.findOne({
      _id: req.params.id
    }).then(project => {
      project.proxies = []; // this is only in case you wanna remove the old ones first
      const proxies = req.body.proxies;
      for(let i = 0;  i < proxies.length; i++) {
        // Add to proxy array on the Project object in the collection
        project.proxies.push({ proxyTitle: proxies[i].title });
      }

      project.save().then(project => {
      res.redirect(`/projects/stakeholders/${project.id}`);
    });
  });
});
bredikhin
  • 8,875
  • 3
  • 40
  • 44
  • Thank you so much for your helpful and detailed answer, it very nearly works, and I can't figure out why it doesn't - it all seemed to work fine, but when I look in my db, only a new empty record has been created. When I console log 'proxies[i]' in the loop it shows something that looks like an object that is exactly the information that I want to store, but if I check the typeof, it's a string. If I JSON.parse it and try to use that, it crashes the programme and tells me that there was an unexpected token '_' in JSON (presumably from the '_id' field). Is this something to do with the loop? – bevc Dec 13 '18 at 04:47
  • @bevc You're probably missing `bodyparser` middleware in your app, take a look here: https://github.com/expressjs/body-parser – bredikhin Dec 13 '18 at 11:15
  • you're right, I actually didn't have body-parser installed for that script! But I tried it with body-parser in both urlencoded true and false, and I still get the same error(s). Thank you very much for your help though, this problem is driving me crazy. – bevc Dec 13 '18 at 11:26