1

Client: HTML5 + JS + localdb Server: Rails3

I'm trying to code small mobile app: the app if a small form that records some contacts info into a local database. Then when clicking on a Sync button it send the contacts to a RoR app.

Trying to follow some best practise I would like to store the data on JSON format before sending it to the RoR app. The JSON variable is building dynamically from a localdb:

on client side:

var myJSON= { 
            jcontacts:[]
        }; 

...
// loop on localdb
for (var i=0; i< vContacts.length;i++)
{                               
    myJSON.jcontacts.push({
        "name"      : vContacts[i][0],
        "email"     : vContacts[i][1],
        "info"      : vContacts[i][2]
    });                                                                                     
}           
var myJSONText = JSON.stringify(myJSON);    //(1) convert array to JSON string                                              

/*
console.log(myJSONText) --> {"jcontacts":[{"name":"John","email":"john@email.com","info":"Owner"},
{"name":"Mary","email":"mary@gmail.com","info":"Doctor"},
{"name":"Gary","email":"gary@email.com","info":"Driver"}]}
*/

var myObject = JSON.parse(myJSONText);// (2) convert JSON string to JSON object, just do it to make sure my var is valid JSON format
myGlobalJSONText = JSON.stringify(myObject); // (3) convert JSON object to JSON string before sending to server

/*
console.log(myGlobalJSONText) --> {"jcontacts":[{"name":"John","email":"john@email.com","insurance":"Medical"},
{"name":"Mary","email":"mary@gmail.com","insurance":"Medical"},
{"name":"Gary","email":"gary@email.com","insurance":"Car"}]}
*/
...
// Ajax
   $.ajax({
        type: "POST",                    
        url : "http://localhost:3000/contacts/multinew",
        cache: false,
        data: myGlobalJSONText,
        success: onSuccess,
        error: onError
    });

On Rails side:

def multinew        
    @vcontacts = JSON.parse(params[:jcontacts])     
    @vcontacts.each {|x| Contact.create(x)}   

    respond_to do |format|
        format.html { redirect_to(@contact)}
      format.xml  { head :ok }
    end
 end

When sending the data, my Rails server replies:

Started POST "/contacts/multinew" for 127.0.0.1 at 2011-04-25 20:49:23 +0700
  Processing by ContactsController#multinew as */*
  Parameters: {"{\"jcontacts\":"=>{"{\"name\":\"John\",\"email\":\"john@email.com\",\"info\":\"Owner\"},{\"name\":\"Mary\",\"email\":\"mary@gmail.com\",\"info\":\"Doctor\"},{\"name\":\"Gary\",\"email\":\"gary@email.com\",\"info\":\"Driver\"}"=>{"}"=>nil}}}
Completed   in 0ms

TypeError (can't convert nil into String):

So my questions are:

1) before trying to fix the Rails part I would like to know if everything is correct on the client javascript code? My assumption using JSON is that if a variable is properly formed on client side (using JSON.stringify) it should be interpreted correctly on server side (using JSON.parse), this is the reason why people use JSON?

2) if the client code side is correct it means I should fixe the ruby code by putting some regex processing? Is this case I cannot see the advantage of using JSON (others the security reason)

Many thanks!

  • Not all browsers support `JSON.stringify` natively, but according to your logs, yours does (correctly). – Marcel Korpel Apr 25 '11 at 14:30
  • If you google for json2.js you can probably find the industry standard library which adds JSON.parse and JSON.stringify according to spec. To address your problem, can you post the JSON as JavaScript sends it? Also, JavaScript supports JSON natively you so you probably don't even need to do any JSON.stringify on your end (since you're using jQuery) – Halcyon Apr 25 '11 at 14:52
  • @Frits: “JavaScript supports JSON natively” → I suppose you meant jQuery? – Marcel Korpel Apr 25 '11 at 16:52
  • @Mark : you mean I should investigate on Rails part now? – RamblingOnRubyOnRails Apr 25 '11 at 17:00

1 Answers1

0

I finally come with this solution:

1/ On client side, I send a JSON object not a JSON stringified variable

2/ On Server side I made a small fixe to transform the has_array variable received to a simple array

ANY BETTER SUGGESTION IS WELCOME!

Client:

{                               
    myJSON.jcontacts.push({
        "name"      : vContacts[i][0],
        "email"     : vContacts[i][1],
        "info"          : vContacts[i][2]
    });                                                                                     
}                                                                   

myJSONText = JSON.stringify(myJSON);    // array to JSON string , I cannot avoid this step before calling the PARSE method hereafter                                                                        
myGlobalJSONText = JSON.parse(myJSONText); // JSON string to JSON object    

Server: The variable is received as an hash_array of has_array elements

{"0"=>{"name"=>"John", "email"=>"john@email.com", "info"=>"Doctor"},
"1"=>{"name"=>"Mary", "email"=>"mary@gmail.com", "info"=>"Driver"},
"2"=>{"name"=>"Gary", "email"=>"gary@email.com", "info"=>"Owner"}}

but we should transform it to an array of has_array elements:

[{"name"=>"John", "email"=>"john@email.com", "info"=>"Doctor"},
 {"name"=>"Mary", "email"=>"mary@gmail.com", "info"=>"Driver"},
{"name"=>"Gary", "email"=>"gary@email.com", "info"=>"Owner"}]

To do so:

def multinew            

@hash_contacts = params[:jcontacts]         
@array_contacts = Array.new
@hash_contacts.each_value {|value| @array_contacts<<value }

@array_contacts.each {|x| Contact.create(x)}   

...