Search code examples
expresspostput

Expressjs / Nodejs route works with POST, but not with PUT


I'm changing nothing but changing the route method from "Post" to "Put", and for some reason that breaks it.

The POST route works fine:

In route in App.js with POST:

 app.post('/editlisting/update',listing.update);

the editListing.jade file that submits to it:

extends layout

block content
  div(class="container")
      ul(class="userlist")
      each listing, i in listings
        li
          h1 #{listing.name}
          form(method='post', action='update' class='regform')
            label Name:
            input(type='text', name='name', value='#{listing.name}')
            br
            label Number of Guests:
            input(type='text', name='noGuests', value='#{listing.noGuests}')
            input(type='hidden', name='id', value='#{listing._id}')
            label Price:
            input(type='text', name='price', value='#{listing.price}')
            input(type='submit', value='Update')
            a(href='/') Home

The Update method in listing.js (I don't change this at all):

      exports.update = function(req,res){
  var conditions = {_id:req.body.id}
  , update = {
       name: req.body.name,
       noGuests: req.body.noGuests,
       price: req.body.price
     }
  , options = { multi: false };

Listing.update(conditions, update, options, callback);

  function callback (err, numAffected) {
    if(err) { throw err; }
    res.redirect('/');
  };

 }

Then when I try to change it to PUT....

app.js:

app.put('/editlisting/update',listing.update);

editListing.Jade:

extends layout

block content
  div(class="container")
      ul(class="userlist")
      each listing, i in listings
        li
          h1 #{listing.name}
          form(method='put', action='update' class='regform')
            label Name:
            input(type='text', name='name', value='#{listing.name}')
            br
            label Number of Guests:
            input(type='text', name='noGuests', value='#{listing.noGuests}')
            input(type='hidden', name='id', value='#{listing._id}')
            label Price:
            input(type='text', name='price', value='#{listing.price}')
            input(type='submit', value='Update')
            a(href='/') Home

This causes my browser to display this error when I press the "Update" button:

4| div(class="container") 5| ul(class="userlist") > 6| each listing, i in listings 7| li 8| h1 #{listing.name} 9| form(method='put', action='update' class='regform') Cannot read property 'length' of undefined

And it points to the line in my editListing.jade file:

   each listing, i in listings

Does anyone know what the problem is?


Solution

  • The simplest way you can do is method overriding

    run npm install method-override

    include it in your application after body-parser something like this

    var express = require('express'),
        bodyParser = require('body-parser'),
        methodOverride = require('method-override')
        app = express();
    
    
    app.use(bodyParser.urlencoded({ extended: true }));
    app.use(methodOverride('_method'));
    

    Then modify your html

     block content
      div(class="container")
          ul(class="userlist")
          each listing, i in listings
            li
              h1 #{listing.name}
              form(method='POST', action='/editlisting/update?_method=PUT' class='regform')
                label Name:
                input(type='text', name='name', value='#{listing.name}')
                br
                label Number of Guests:
                input(type='text', name='noGuests', value='#{listing.noGuests}')
                input(type='hidden', name='id', value='#{listing._id}')
                label Price:
                input(type='text', name='price', value='#{listing.price}')
                input(type='submit', value='Update')
                a(href='/') Home
    

    then you'll be able to use

    app.put('/editlisting/update',listing.update);