Marcia Yudkin
Marcia Yudkin

Reputation: 25

Request not going as 'PUT' after clicking 'Update' button, instead going as 'POST'

I just learning Backbone JS and below is the code for which Iam not understanding how to do PUT request. It keeps sending request as 'POST' only, how do I make 'PUT' operation. Please suggest me what changes need to do in the code:

Actually iam trying to practice this video: https://www.youtube.com/watch?v=FZSjvWtUxYk , I just stucked at 'Update' Operation.

The output would look like this: http://backbonetutorials.com/videos/beginner/#/edit/i4zofel9gi7aq64ggxsu

In above link, 'update' operation works well. BUT for me, request not going as 'PUT' after clicking 'Update' button, instead going as 'POST'. Please suggest me what went wrong.

FYI, iam using 'Server' as 'Java Code ie., DAO, Restful service'

Here is the code:

<html>
<head>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">
<script type="text/javascript">
    /*$.getJSON('api/users/1',function(data){

        console.log(data);
    });*/
</script>


</head>

<body>

    <div class="container">
        <h1>User Manager</h1>
        <hr/>
        <div class="page"></div>
    </div>

    <script type="text/template" id="user-list-template">
        <a href="#/new" class="btn btn-primary">New User</a>    
        <hr>

        <table class="table stripped">
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Age</th>
                </tr>
            </thead>
            <tbody>
                <% _.each(users,function(user) {  %>
                <tr>
                    <td><%= user.get('firstName')  %></td>
                    <td><%= user.get('lastName')  %></td>
                    <td><%= user.get('age')  %></td>
                    <td><a href="#/edit/<%= user.id %>" class="btn">Edit</a></td>
                </tr>
                <% }); %>
            </tbody>

        </table>
    </script>

    <script type="text/template" id="edit-user-template">
        <form class="edit-user-form" >
            <legend><%= user ? 'Update' : 'Create' %>  User</legend>
            <label>First Name</label>
            <input type="text" name="firstname" id="firstname" value="<%= user ? user.get('firstName') : '' %>"/>
            <label>Last Name</label>
            <input type="text" name="lastname" id="lastname" value="<%= user ? user.get('lastName') : '' %>" />
            <label>Age</label>  
            <input type="text" name="age" id="age" value="<%= user ? user.get('age') : '' %>"/>
            <hr/>
            <% if(user) { %>
                <input type="hidden" name="id" value="<%= user.id %>">
            <% }; %>
            <input type="submit" value="<%= user ? 'Update' : 'Create' %> User" />
        </form>
    </script>

    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.7.0/underscore-min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/backbone.js/1.1.2/backbone-min.js"></script>

    <script type="text/javascript">

        var Users = Backbone.Collection.extend({
            url: 'api/users'
        });     

        var User = Backbone.Model.extend({
            urlRoot: 'api/users'
        })

        var UserList = Backbone.View.extend({
            el:'.page',
            render: function(){
                var that = this;
                var users = new Users();
                users.fetch({
                    success: function(usersList){
                        var template =  _.template($('#user-list-template').html())({users: usersList.models});                         
                        that.$el.html(template);
                    }
                });

            }
        });

        var EditUser =  Backbone.View.extend({
            el: '.page',
            render: function(options){
                if(options.id){
                    var that = this;
                    var user = new User({id:options.id});
                    user.fetch({
                        success: function(user){
                            console.log('Updating User...');
                            var template = _.template($('#edit-user-template').html())({user: user});
                            that.$el.html(template);
                        }
                    });
                } else {    
                    console.log('Creating User...');
                    var template = _.template($('#edit-user-template').html())({user: null});
                    this.$el.html(template);
                }
            },
            events:{
                'submit .edit-user-form':'saveUser'
            },
            saveUser : function(e){
                e.preventDefault();
                var user = new User({id: $('#id').val()});
                var userDetails = {firstName: $('#firstname').val() ,lastName: $('#lastname').val() ,age: $('#age').val() };
                user.save(userDetails, 
                    {
                     success :  function(user){
                        console.log('INSIDE SUCCESS..')
                        router.navigate('',{trigger:'true'});
                    },
                    type: 'put'
                });
            }

        })

        var Router = Backbone.Router.extend({
            routes:{
                '':'home',
                'new': 'editUser',
                'edit/:id': 'editUser'
            }
        });


        var userList = new UserList();
        var editUser =  new EditUser();

        var router = new Router();
        router.on('route:home',function(){
            console.log('we have loaded the home page.');
            userList.render();
        }); 
        router.on('route:editUser',function(id){
            console.log('Show User Form.');
            editUser.render({id:id});
        });

        Backbone.history.start();
    </script>

</body>

</html>

Upvotes: 0

Views: 92

Answers (1)

dannymilsom
dannymilsom

Reputation: 2406

It looks like the value assigned to your models id attribute is undefined - so Backbone thinks you wanted to create a new model - and sends a POST request.

For Backbone to send a PUT request we don't need to explicitly pass the name of a HTTP method, we just need to specify a valid id attribute for a Model before calling save().

I see you are trying to do that inside the saveUser() method on the line

var user = new User({id: $('#id').val()});

However there is no such element with the an id of 'id' in your template snippets. I expect that you are actually trying to get the value stored in the hidden input element with the name 'id'?

<input type="hidden" name="id" value="<%= user.id %>">

But as you're not getting that value, your model now has an id attribute of undefined.

Under the hood Backbone specifies the appropriate HTTP method by calling isNew() on your model. Like so (taken from the backbone source code)

method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');

Your model is returning true when we call isNew(), so the method argument passed to the sync() method is 'create', so a POST request is sent. We can see this by doing a quick test

var model = new Backbone.Model();
model.set({id: undefined});
model.isNew(); // returns true

You could check all this by changing your selector to something like this

var user = new User({id: $("input[name='id']").val()});

If that works we've found the problem. I'd then try and serialize the form inputs instead of using jQuery selectors to get particular values - as that is a nicer approach.

Upvotes: 1

Related Questions