I get "Status: 400 - Bad request" when I try to create _design document(view)


#1

I have tried to create a _design document when I was studying at REST API documentation. But my ajax function response status: 400. It’s got five different meaning. I guess in my case its mean is “Invalid JSON” or “Invalid parameter in HTTP query or JSON body”

400	Bad data encoding
400	bad_request
400	Invalid attachment
400	Invalid database/document/revision ID
400	Invalid JSON
400	Invalid parameter in HTTP query or JSON body

I’ve tried create a view simplicity. I couldn’t find any reasons.
What’s wrong with my codes?

$("#create").on("tap", function() {

     var view  =  {
            "language": "javascript",
            "views": {
                         "user": {
                                    "map": "function(doc) {if (doc.username) {emit(doc)}}"
                         }
             }
     }

    console.log(view);

    $.ajax({
             url: "http://localhost:5984/user/_design/user",
             type: 'PUT', 
             data: view,
             success: function (data, textStatus, xhr) {
                        console.log(xhr);
                    },
             error: function (xhr, statusText, error) {
                        console.log(xhr);
                    }
           }); 
  });

ps: The port number - that was used by me - is 5984. But the port is 59840 at the documentation. I get “status:0” when I use port 59840.


#2

Um, what platform is this on, and what sort of app are you writing?

It kind of looks like you’re using PhoneGap (or Cordova). In that case your URL is definitely wrong (you’re trying to reach some TCP port on your device, which just isn’t going to work.) See our PhoneGap plugin docs for how to get the base URL of the Couchbase Lite REST API.


#3

Hi Jens,

thank you for your quick respond. You’re right. My platform is Cordova and I’ve been using javascript and REST API (I’d forgotten add platform and others :blush: ).

I like the Couchbase’s logic. It offers effective solutions for different problems. I’ve been trying to learn how to use Couchbase with PhoneGap in a project. There are a lot of documentations. I’ve been reading for 2 weeks.

In fact thanks to you, I could watch and read lots of guides include doc.couchbase.com, developer.couchbase.com/mobile, forum.couchbase.com, your google forums and the following sources. In the beginning I got confused, but now I’m better (from chaos to harmony).

  • Your webinar (Sync & Swim With CouchDB for IOS)
  • J.Chris Anderson (TodoLite-PhoneGap & CouchChat-PhoneGap)
  • Lorin Beer (anoter app)
  • Andrew Reslan (Introduction to Couchbase Sync Gateway)
  • And other Sync Gateway sources…

Nevertheless I can be missed somethings because I try to get better my English.

I think, Javascript is a very flexible language and for this reason there are lots of different library that was created by different person and logic. And for the same reason I think, Javascript is the most difficult way to develop a complex mobile application though I have never used Java. But I have the will to succeed! :smile:

Actually, some related parts of my codes like the following ;

var cblUrl;
var dbName = "user";

// I try to get Couchbase URL on DeviceReady event
if(window.cblite) {
     window.cblite.getURL(function(err, url) {
            if(err) {
                console.log("error launching Couchbase Lite: " + err);
            } else {
                console.log("Couchbase Lite running at " + url);
                cblUrl = url;
            }
     });

} else {
     console.log("error, Couchbase Lite plugin not found.");
}


// I try to create a View when a user on tap Create button
$("#create").on("tap", function() {

   var view  =  {
       "language" : "javascript",
       "views" : {
            "user" : {
                "map" : "function(doc) {if (doc.username) {emit(doc)}}"
            }
        }
    }

    $.ajax({
           url: cblUrl + dbName + "/_design/user",
           type: 'PUT', 
           data: view,
           success: function (data, textStatus, xhr) {
                    console.log(xhr);
           },
           error: function (xhr, statusText, error) {
                    console.log(xhr);
                }
    });

});

#4

I’m not sure if you’re asking a question here, or just saying that you fixed your problem.

And for the same reason I think, Javascript is the most difficult way to develop a complex mobile application

In my opinion, it’s easier to use Couchbase Lite from a ‘native’ language like Objective-C, Swift, Java, C#, because we have a higher level procedural API instead of having to put together REST calls.


#5

Thank you for your comment.
Unfotunately, I couldn’t fix my problem. Still I get status 400 message. I’ve added my running codes the above.


#6

What’s the full error? There should be a message along with the 400.

Also, what is the complete URL? (Have your code log it before it sends the XHR.)


#7

By the way, that emit call is wrong. It takes two parameters: a key and a value. doc isn’t an appropriate value for either one. Looks like you might want to emit doc.username as the key. If you don’t need a particular value, use null for that parameter.


#8

Thank you again,

I’ve changed the emit function calling. But it doesn’t matter. I couldn’t create a view.

var view  =  {
               "language" : "javascript",
                "views" : {
                     "user" : {
                          "map" : "function(doc) {if (doc.username) {emit(doc.username, null)}}"
                      }
                 }
             }

But still I cannot find my mistakes. Is there any example regarding Couchbase Lite REST API?

Have a nice day.


#9

You haven’t answered the questions I asked.


#10

Ooops… I’ve seen your questions after you warned me.

full error xhr:
{“readyState”:4,“responseText”:"",“status”:400,“statusText”:“Bad request”}

complete URL:
http://localhost:5984/user/_design/user

I used the following jQuery ajax method;

$.ajax({
   url: cblUrl + dbName + "/_design/user",
   type: "PUT", 
   data: {
              "views" : { 
                     "user" : {
                          "map" : "function(doc) { emit(doc.username, null) }"
                     }
              }
         },
   beforeSend: function(xhr, contents) {
         console.log("beforeSend-xhr: " + JSON.stringify(xhr));
         console.log("beforeSend-contents: " + JSON.stringify(contents));
   },
   success: function (data, textStatus, xhr) {
         console.log(JSON.stringify(xhr));
   },
   error: function (xhr, statusText, error) {
         console.log("URL: " + this.url);
         console.log("error-xhr: " + JSON.stringify(xhr));
   }
});

You might need to beforeSend contents. So I’ve added my beforeSend XHR and beforeSend contents the below If;

beforeSend XHR: {“readyState”:0}

beforeSend contents:

{
    "url":"http://localhost:5984/user/_design/user",
    "type":"PUT",
    "isLocal":true,
    "global":true,
    "processData":true,
    "async":true,
    "contentType":"application/x-www-form-urlencoded; charset=UTF-8",
    "accepts":{
        "*":"*/*",
        "text":"text/plain",
        "html":"text/html",
        "xml":"application/xml, text/xml",
        "json":"application/json, text/javascript",
        "script":"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
    },
    "contents":{
        "xml":{},
        "html":{},
        "json":{},
        "script":{}
    },
    "responseFields":{
        "xml":"responseXML",
        "text":"responseText",
        "json":"responseJSON"
    },
    "converters":{
        "text html":true
    },
    "flatOptions":{
        "url":true,
        "context":true
    },
    "jsonp":"callback",
    "data":"views%5Buser%5D%5Bmap%5D=function(doc)+%7B+emit(doc.username%2C+null)+%7D",
    "dataTypes":["*"],
    "crossDomain":true,
    "hasContent":true
}

The above "dataTypes" seems :["*"]. Also I’ve tried to ajax put dataType: "json" parameter. It doesn’t matter.


#11

As I said in my very first reply on this thread, that URL is wrong — there’s nothing at localhost:5984. That would be the default address of a CouchDB server, but this is not CouchDB. The URL of Couchbase Lite is the one that’s given to your code at startup by the plugin.

I feel like we’re going around in circles. I can’t help you unless you listen to my responses.


#12

I thought, if I use cblite.getURL function then I can obtain the correct URL.

I will take your advice and I’ll try to find correct URL. Again thank you very much :smile:

my code’s part

if(window.cblite) {
     window.cblite.getURL(function(err, url) {
            if(err) {
                console.log("error launching Couchbase Lite: " + err);
            } else {
                console.log("Couchbase Lite running at " + url);
                cblUrl = url;
            }
     });

} else {
     console.log("error, Couchbase Lite plugin not found.");
}

#13

Are you on iOS or Android? The URL will vary by platform, I think, and I’m more familiar with iOS.


#14

I’ve been trying on Android emulator.
Also I couldn’t create a document with this URL. But I can create database.


#15

I’ve tried vanilla XHR (using XMLHttpRequest) . My console gave outputs as the below.

error getAllResponseHeaders: date: Mon, 17 Nov 2014 20:49:31 GMT
server: D. Rogatkin’s TJWS with Android support (Acme.Serve)/Version 1.94, $Revision: 1.236 $,Couchbase Lite 1.0.0-beta

My plugin version’s seemed as beta.

I had installed using command of cordova plugin add com.couchbase.lite.phonegap .
And then I’ve tried to uninstall and re-install plugin using command of cordova plugin add https://github.com/couchbaselabs/Couchbase-Lite-PhoneGap-Plugin.git.

ta-daaa… :slight_smile:

Now, I’m using Couchbase Lite devbuild-0 version. And I think my URL changed as you said.

My current URL is so long http://7d082bf2-6f7a-4f1e.........efd3b558@localhost:5984/

And now, still I couldn’t create a view. But I’m feeling closer to success.

Thank you again…

PS: The plugin that’s at plugins.cordova.io may be required to upgrade by Couchbase.


#16

Oh, crap! Very sorry about that. It sounds like you’ve run into an issue we just discovered a few days ago, where the Cordova registry points to an old version of our plugin (probably dating from early 2014.) We’re getting it fixed, but it’s not instant because it’s an external registry that we don’t own.

Hope things are working well with the updated plugin.