简体   繁体   中英

PHP + Backbone.js Save callback keeps raising an error

First, I'd like to say that I'm a graphic designer at first, so I'm really sorry if I'm missing something really stupid but I can't figure out the problem by myself :/.

I'm running into a problem when saving a model with backbone.js and PHP. I'm using Restler to handle the PHP calls.

I'm working on an admin for a website that we'll present conferences. When I add a speaker to a conference, I create an entry in the pl_speakers table and I want to retrieve its id in order to add it to the corresponding conference entry.

My PHP code looks like this :

function post($id = NULL, $request_data = NULL) {

    $sql = "INSERT INTO pl_speakers(id, firstName, name, job, site, mail, video, cv) VALUES (
        '',
        '".$request_data["firstName"]."',
        '".$request_data["name"]."',
        '".$request_data["job"]."',
        '".$request_data["site"]."',
        '".$request_data["mail"]."',
        '".$request_data["video"]."',
        '".$request_data["cv"]."'
    )";

    $req = $this->db->query($sql);
    $response = array("id" => $this->db->lastInsertId());
    return json_encode($response);
}

and my javascript looks like that

    onAddClick: function(){
        var speaker = new speakerModel;
        this.speakers.add(speaker);
    },
    onAddSpeaker: function(speakerModel){
        speakerModel.save(speakerModel, {  success:$.proxy(this.onSpeakerSaved, this),  error: $.proxy(this.onSpeakerNotSaved, this)});
    },

    onSpeakerSaved: function(speakerModel, response){
        console.log(response)
    },

When I look in Chrome's Network panel, the response send by the php script is "{\\"id\\":\\"128\\"}" but the response logged in "onSpeakerSaved" doesn't appear and instead I have this error :

Uncaught TypeError: Cannot use 'in' operator to search for 'id' in {"id":"128"}  
f.extend.setbackbone-min.js:9  
f.extend.save.b.successbackbone-min.js:12  
f.extend._Deferred.e.resolveWithjquery-min.js:2  
wjquery-min.js:4  
f.support.ajax.f.ajaxTransport.send.d  

I get this error whatever the php function returns (even if it's the whole model) but if it doesn't return anything then the error disappears.

I've searched the previous questions on the subject and it seems the response must be a json object with an "id" property, which it is here, so I'm totally stuck and can't figure out where I'm wrong :/.

Again, if I'm missing a stupid thing, I'm really sorry but I would really appreciate a hand on this one :)

EDIT : Here's the whole php class if it can be of any help but I feel like it's more on the javascript side and how the response is handled by Backbone. I also added the onAddClick JS method.

class Speakers {
public $db;

function __construct() {
    $this->db = new PDO("mysql:dbname=".DB_NAME.";host=".DB_SERVER, DB_USER, DB_PWD);
}

function get($id=null) {
    return is_null($id) ? $this->getAll() : $this->getSpeaker($id);
}
function getAll() {
    $sql = "SELECT * FROM pl_speakers";
    return $this->getJSON($sql);
}
function getSpeaker($id) {
    $sql = "SELECT * FROM pl_speakers WHERE id='".$id."'";
    return $this->getJSON($sql);
}
function getJSON($sql) {
    $req = $this->db->query($sql);

    $data = array();
    while($row = $req->fetchObject()) 
    { 
        $data[] = $row;
    } 

    return json_encode($data);
}

function post($id = NULL, $request_data = NULL) {

    $sql = "INSERT INTO pl_speakers(id, firstName, name, job, site, mail, video, cv) VALUES (
        '',
        '".$request_data["firstName"]."',
        '".$request_data["name"]."',
        '".$request_data["job"]."',
        '".$request_data["site"]."',
        '".$request_data["mail"]."',
        '".$request_data["video"]."',
        '".$request_data["cv"]."'
    )";

    $req = $this->db->query($sql);
    $response = array("id" => $this->db->lastInsertId());
    return $this->getSpeaker($this->db->lastInsertId());
}

function put($id = NULL, $request_data = NULL) {
    $sql = "UPDATE pl_speakers
            SET firstName = '".$request_data["firstName"]."',
            name = '".$request_data["name"]."',
            job = '".$request_data["job"]."',
            site = '".$request_data["site"]."',
            mail = '".$request_data["mail"]."',
            video = '".$request_data["video"]."',
            cv = '".$request_data["cv"]."'
            WHERE id = '".$id."'";

    $req = $this->db->query($sql);
}
function delete($id = NULL) {
    $sql = "DELETE FROM pl_speakers WHERE id='".$id."'";
    $req = $this->db->query($sql);
}

Restler takes care of converting PHP data returned by your methods in to JSON/XML/YAML/PLIST/AMF based on what client is requesting and what formats you want your API to support

$restler->setSupportedFormats('JsonFormat', 'PlistFormat', ...);

So you should not try doing the JSON encode yourself, all you need to return is an array.

Here is the modified version of your class

<?php

class Speakers {
    public $db;

    function __construct() {
        $this->db = new PDO("mysql:dbname=".DB_NAME.";host=".DB_SERVER, DB_USER, DB_PWD);
    }

    function get($id=null) {
        return is_null($id) ? $this->getAll() : $this->getSpeaker($id);
    }
    private function getAll() {
        $req = $this->db->query("SELECT * FROM pl_speakers");
        return $req->fetchAll();
    }
    private function getSpeaker($id) {
        $req = $this->db->query("SELECT * FROM pl_speakers WHERE id='".$id."'");
        return $req->fetchAll();
    }   
    function post($id = NULL, $request_data = NULL) {

        $sql = "INSERT INTO pl_speakers(id, firstName, name, job, site, mail, video, cv) VALUES (
            '',
            '".$request_data["firstName"]."',
        '".$request_data["name"]."',
        '".$request_data["job"]."',
        '".$request_data["site"]."',
        '".$request_data["mail"]."',
        '".$request_data["video"]."',
        '".$request_data["cv"]."'
        )";

        $req = $this->db->query($sql);
        $response = array("id" => $this->db->lastInsertId());
        return $this->getSpeaker($this->db->lastInsertId());
    }

    function put($id = NULL, $request_data = NULL) {
        $sql = "UPDATE pl_speakers
            SET firstName = '".$request_data["firstName"]."',
        name = '".$request_data["name"]."',
        job = '".$request_data["job"]."',
        site = '".$request_data["site"]."',
        mail = '".$request_data["mail"]."',
        video = '".$request_data["video"]."',
        cv = '".$request_data["cv"]."'
        WHERE id = '".$id."'";

        $req = $this->db->query($sql);
    }
    function delete($id = NULL) {
        $sql = "DELETE FROM pl_speakers WHERE id='".$id."'";
        $req = $this->db->query($sql);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM