Ionic Framework has recently become one of the hottest mobile frameworks around. It makes it incredibly easy to write great user interfaces for mobile applications. However, part of the challenge is also managing data, fetching from the back-end server and saving the data locally for when the device is offline.

Couchbase Mobile handles this for you and with the Apache Cordova plugin, it’s a breeze!

In this tutorial, you will learn how to:

  • Include Couchbase Lite in your Ionic project.
  • Use the Ionic UI components to display the data onscreen.
  • Run the application on the iOS / Android simulator.

The Prerequisites

  • Ionic Framework 1.0+
  • Apache Cordova 5.0+
  • The Android SDK if building for Android
  • A Mac with Xcode installed if building for iOS

Getting Started

Before we start coding it is important we create a new project and configure all necessary plugins and components. From the Command Prompt (Windows) or Terminal (Mac / Linux), run the following to create a new Ionic project:

Remember, if you’re not using a Mac, you cannot add and build for the iOS platform.

For this project to be successful, there are a few Apache Cordova plugins that must be installed. With the Ionic project as your current working directory in the Command Prompt or Terminal, run the following commands:

This will install the Apache Cordova whitelist plugin that will allow us to communicate with external services and the Couchbase PhoneGap plugin that will allow for using Couchbase in our application.

Including the AngularJS RESTful Library

Using Couchbase Lite happens through RESTful APIs exposed through the Apache Cordova plugin. A full list of these API endpoints can be found in the official Couchbase documentation. However, there is an AngularJS wrapper library available to make calling these endpoints a lot easier.

Download the latest ng-couchbase-lite release found on GitHub and include the ng-couchbase-lite.min.js file found in the dist directory into your project’s www/js/ folder.

With the file included in your project, open the index.html file and include the JavaScript file like so:

Notice that the script was included above the project’s www/js/app.js.

The final thing needing to be done before ng-couchbase-lite can be used is it needs to be injected into AngularJS. This can be done by opening the project’s www/js/app.js file and changing the angular.module to look like the following:

The AngularJS wrapper can now be used through the project.

Polishing the Index File

A few tweaks need to be made to the project’s www/index.html to take full advantage of this tutorial. The first of which is adding some meta information to compliment the whitelisting plugin. It is more necessary for Android than iOS. Near the other meta tags, include the following:

This just tells your project that you want to work with certain scripts.

The other tweak you want to do is inside your body tags. Replace everything inside the body with the following:

You should be good to go at this point

Using a Global Database Variable

To save us the trouble of having to open the database on every view, we’re just going to create a variable global to the project. In the www/js/app.js file below angular.module include the following:

This will get set later when we initialize the database.

Configuring the UI Router

Ionic Framework uses the AngularJS UI-Router, so we’re going to leverage it when handling our views and controllers. Inside the project’s www/js/app.js file, add the following code:

We have two routes, one to our lists view and one to our tasks view. The tasks view however requires an extra parameter which we’re identifying as listId. This is because when we navigate to the tasks view we want to provide the parent list item that the task belongs to. It will help us for querying our data. Ignore the controllers for now, because we’re going to create them later.

Initializing the Database and Views

The first thing to do when using the Couchbase PhoneGap plugin is to create a database. Then, you can register views to query the documents that will reside in the database. Couchbase Views are map/reduce queries that build the index incrementally as new documents are saved to the database. They are completely different to user interface Views!

Inside your project’s www/js/app.js file, we’re going to include a few things in the AngularJS run method:

Here’s what’s happening step by step:

  1. You first check to make sure the plugin exists (installed and running). If it exists, then create a new database if the desired database does not already exist. If the database creation is successful, we’re going to create two views, one for getting the todo lists, and one for getting the tasks. For this tutorial, the database we’re creating is called todo.
  2. We’re creating a view called tasks and lists, both inside of the _design/todo design document. In regards to the Couchbase views. The lists view will return all documents that have a doc.type of list and that have a title property. However, only the title and document revision are returned with the document id. This is to keep things light-weight. The tasks view will return all documents that have a doc.type of task as well as some title property and parent list_id property. In this particular view, only the title, document revision, and list id are returned with the document id.

Creating the Controllers

The Todo List Controller

Inside the www/js/app.js file of your project, go ahead and create the following controller:

A little explanation on our plans here. The $scope.lists object will hold all Couchbase documents that the particular view will have access to. $scope.insert of course will be responsible for inserting data into Couchbase Lite and $scope.delete will be responsible for deleting data.

So starting with the $scope.insert function:

Instead of creating a separate view for inserting data we’re just making use of an $ionicPopup. With the result we are adding it to an object and also adding a document type for future references. This object is then inserted into the database at which point you can choose to perform certain tasks depending on its success or failure.

The next function to worry about is the $scope.delete function:

A few things are happening here. First we attempt to delete the list document via the particular id and revision. If that is successful we then query our task view for any tasks that had a parent of our recently created document. We narrow our search by making use of the start_key option. For every task document that does match, remove it at well so that way it is not orphaned by the delete of the parent.

The parameter passed to the delete function is an object.

Wait a second though! How do we search for documents to display in our list? There are two parts behind what we’re about to do. The first involves quering the view that we created when making a fresh database. This can be done like the following:

That will query the view for todo lists when the view loads, but how do we constantly look for changes? Since we started listening for changes in the run method, we can choose to display what we’ve heard:

The above code will listen for the couchbase:change event. If it is triggered, it will loop through all the changes and determine whether it will be deleting a document from the list or upserting a document to the list. I say upserting because it will insert it if it doesn’t exist or update it if it does.

The Task List Controller

Inside the www/js/app.js file of your project, go ahead and create the following controller:

A few things are happening here. The $scope.todoList variable holds the list id that was passed in from the previous todo list view. It is the id of the list that was selected. The $scope.tasks object is similar to what we saw in the TodoListsController with the $scope.lists object. This time it will just be storing task information. The $scope.insert and $scope.delete will also be very similar to what we saw in the TodoListsController. However, $scope.back is new and is responsible for taking us one level back in the history stack when tapping on the back arrow inside the application.

So lets fill these functions with some code, starting with the $scope.insert function:

Like in the other controller, this will also be using the $ionicPopup for entering data. The result will be added to an object with a type and the id of the list that this child task belongs to. This object is then inserted into the database.

Next up is the delete functionality for removing tasks from Couchbase Lite:

Notice how much easier this delete function was in comparison to deleting lists. This is because we don’t have to worry about orphaning data. Just pass in the particular task id and revision to delete and then it is done.

Going back to the back function responsible for taking us back to the todo list:

Nothing special here, but it is important because iOS devices don’t have a hardware back button. Less important for Android, but still nice to have for consistency.

Just like with our todo list controller, we have to worry about presenting the data to the screen. It will in fact be very similar to what we saw in the other controller. Starting with querying the view for tasks:

In the above code we are querying the view, but also checking to make sure that the document results share the same todo list parent, through the use of the start_key. If the results match, then add them to our tasks object.

When it comes to our listener, again it will be very similar to what we’ve already seen:

Instead of filtering for lists, we’re instead filtering for tasks.

Creating the UI Views

There will be two views in this application:

  • A view for creating, viewing, and deleting lists
  • A view for creating, viewing, and deleting tasks

The layout and functionality between the two will be near identical. If a www/templates directory doesn’t already exist in your project, go ahead and create it.

The Todo List View

In your project’s www/templates, create a new file called todolists.html and add the following code:

There are a few things to note about what you see above. First off, there will be a navigation button with a plus icon which will be how users create new lists. When clicked, it will call the insert() method that we created in our controller. The next thing to notice is how we’ve chosen to create our ion-list. We’ve chosen to give it swipe features similar to common mail apps for iOS and Android. This comes in combination with the ion-option-button that we’ll use for deleting lists.

The final point in this view is the ng-repeat that we’re using to loop through all lists. When we click on a list item, the list id will be passed via the ui-sref call.

The Task List View

In your project’s www/templates, create a new file called tasks.html and add the following code:

Again, this is very similar to the todo list view. There are two major differences between the two, however. First, notice that this view has a left button with an arrow icon that calls our back() method. We now have two menu buttons on this screen. Second, notice the ng-if statement that exists in the repeating ion-item tag. We only want to show the task if it has a parent that matches the list that we’ve chosen.

Testing Your Project

Testing for Android

With a device connected or a simulator running, from the Command Prompt or Terminal, run the following two commands to build and install the APK file:

Testing for iOS

There are two good ways to do this. You can either build the project and open it with Xcode, or you can build and emulate the application without launching Xcode. The first can be done like so:

Then open the project’s platform/ios/ directory and launch the Xcode project file.

If you’ve installed the Node Package Manager (NPM) package ios-sim, you can do the following:

Solving Any Gradle Dependency Problems

At compile time for Android, you may run into the following error message:

To resolve this, you must extend the Gradle build file for Android as outlined in the official Apache Cordova documentation.

Create platforms/android/build-extras.gradle in your project and add the following:

Conclusion

Using the Couchbase PhoneGap plugin, we’ve created a mobile todo-list application that does all transactions locally. We used AngularJS to easily connect to the RESTful endpoints that Couchbase Lite exposes.

The next Ionic Framework tutorial in this series will go over how to replicate data between the local device and Couchbase Sync Gateway so data can be shared between devices and platforms.

This series can be downloaded in full from the Couchbase Labs GitHub page.

Posted by Nic Raboy, Developer Advocate, Couchbase

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

104 Comments

  1. So much coupling to other components in your views! Perhaps place the insert/update/delete logic into separate Action-classes to decouple them from any particular UI, then call them when the insert/update/delete triggers are sent from the view. e.g. <my-todo-ui on-insert=\”doAction(\’insertToDo\’, data)\” on-update=\”doAction(\’updateToDo\’, data)\” …=\”\”>

    1. Hey thanks for your comment!

      I think it comes down to preference as I\’ve not read in the Ionic documentation to do or don\’t do that. I\’m not disagreeing with you as I think you have a very valid approach, but I think it may be too advanced for many readers of this tutorial. I was trying to accommodate all developers, beginner and experienced.

      Thanks again for your suggestion πŸ™‚

  2. Cristian Rodriguez July 28, 2015 at 1:37 am

    Thanks!

  3. When I run the git project on iOS emulator (ionic emulate ios), it is failing while creating the database. error returned is just null. What could be happening?

    Here is the request: {\”method\”:\”PUT\”,\”url\”:\”http://lite.couchbase./todo\”,\”withCredentials\”:true}and response: {\”data\”:null,\”status\”:0,\”config\”:{\”method\”:\”PUT\”,\”transformRequest\”:[null],\”transformResponse\”:[null],\”url\”:\”http://lite.couchbase./todo\”,\”withCredentials\”:true,\”headers\”:{\”Accept\”:\”application/json, text/plain, */*\”}},\”statusText\”:\”\”}

    1. That\’s odd!

      What version of iOS are you testing on and what version of Apache Cordova? Can I confirm that you\’ve installed all necessary plugins AFTER adding the iOS platform?

      Thanks,

      1. Josip Bosnjak March 7, 2016 at 4:01 pm

        I\’m having the exact same problem. createDatabase() is being called and it goes to error callback, error is null.

        I\’m running the app on Samsung Galaxy S3.

        1. Any more information you can give me? Android version? How you\’re deploying? etc.

          Best,

          1. Android 4.1.2. I\’m deploying on device using ionic build android -> ionic run android.

            However, if it helps, I ran it in ios emulator and it works.

          2. Opened a ticket for you here:

            https://github.com/couchbase/c

            Best,

          3. Are you still experiencing problems with this?

          4. I have the same problem running the TodoliteIonic app createDatabase promise is rejected but the error is empty. I cannot see anything in the logcat other than my logs before and after error
            Running android 4.2.2
            On another device running 5.0.2
            I see Failed to load resource: the server responded with a status of 403 (Forbidden)

            Works fine on android 6+

          5. Hey Frank, can you paste your full logcat for each failed device? Feel free to use separate comments for each.

            Thanks,

          6. Currently away from my machine at the moment but I\’ve done a bit more digging and have found that on the devices that fail the Authorisation header is missing.
            No idea how it\’s being set on the devices that work but it is definitely there.

            I\’ll send my logs as soon as I can.

          7. Ok I\’ve dug into the Android plugin and found this

            Credentials requestCredentials = credentialsWithBasicAuthentication(request);

            if (allowedCredentials != null && !allowedCredentials.empty()) {

            if (requestCredentials == null || !requestCredentials.equals(allowedCredentials)) {

            Log.d(Log.TAG_LISTENER, \”Unauthorized — requestCredentials not given or do not match allowed credentials\”);

            response.setHeader(\”WWW-Authenticate\”, \”Basic realm=\”Couchbase Lite\”\”);

            response.setStatus(401);

            return;

            ////For some reason we do not receive a 401 on the device. The error return is null

            }

            Log.v(Log.TAG_LISTENER, \”Authorized via basic auth\”);

            } else {

            Log.v(Log.TAG_LISTENER, \”Not enforcing basic auth — allowedCredentials null or empty\”);

            }

            credentialsWithBasicAuthentication(request) returns null on some devices because the Basic Authorisation header hasn\’t been set.

            I\’m not setting this anywhere. To fix this I\’ve had to amend makeRequest in ng-couchbase-lite.js to

            makeRequest: function(method, url, params, data) {

            var deferred = $q.defer();

            var settings = {

            method: method,

            url: url,

            withCredentials: true,

            headers: {

            \’Authorization\’: this.auth

            }

            };

            if (params) {

            settings.params = params;

            }

            if (data) {

            settings.data = data;

            }

            $http(settings)

            .success(function(result) {

            deferred.resolve(result);

            })

            .error(function(error) {

            deferred.reject(error);

            });

            return deferred.promise;

            }

            Where this.auth is a Base64 encoded string of the info returned by cblite.getURL

            Whilst this doesn\’t seem to have broken anything I\’d like to understand how the Authorisation header is being set on devices that were working.

          8. Interesting…

            Are you using a custom ROM for Android by chance? I\’m wondering if this is an Angular thing, less of a Couchbase thing. If your devices are processing JavaScript differently, then maybe that is the problem. What kind of devices or emulators are you using for each of these versions of Android?

            Best,

          9. Sorry for late reply been away πŸ™‚
            All Android devices have a standard ROM. I agree it looks more like an Angular issue but cannot see where the basic auth info was being set.

          10. You might want to take this to the forums

  4. AndrΓ© Miranda August 19, 2015 at 12:12 pm

    Excelent tutorial!
    Serves even as an introduction to Ionic.

    Small tip: maybe adding the link to the second part of the article makes it easier for the reader to follow πŸ˜‰

    1. Thanks for the tip! I\’ve gone ahead and linked this first article to the second in the series πŸ™‚

  5. hi,

    how can i find out the path of js-lib used by CS?
    And how can i add sef-defined js-lib to CS?

    1. I\’m a bit confused here:

      1. What are you referring to when you say \”js-lib\”?
      2. What \”self-defined js-lib\” are you referring to?

      Best,

      1. hi,
        I want to know where the native js function comes from .
        And if i want to define my js function sets , i will save them in a file with the .js extent name, where should i put the js file ?

        1. I am still confused. What native js function are you talking about?

          Please be very descriptive as it will allow me to better help you.

          Best,

          1. eg: where does filter function come from? parseInt?

          2. Are you referring to inside the change event? If yes, we are just looking at a particular property in the NoSQL documents.

            If you\’re referring to something else, please be specific. The more information you give me, the better I can help you.

            Regards,

          3. thank you!
            And in face , i want to know that what built-in functions i can use?
            Is there a built-in function like \’ substring\’?

            Does the CS import the underscore.js?

          4. hi,
            does the CS only own 10 buckets?

  6. Thanks for the tutorial!

    When I try to run this on my Android 6, Nexus 5, I get \”invalid database\” error at the createDatabase step. Can you please help me figure out what might be wrong.

    Thanks

    1. What do your full logs say?

      1. Pardon the n00b question Nic, but where do I find the logs and how do I enable it in the ionic environment?

        1. Apparently, if I have an uppercase character in the database name, it fails. When I used only lowercase letters it worked!

          1. Happy to hear you got it working πŸ™‚

        2. For Android, you can see the following to get in-depth log information:

          https://blog.nraboy.com/2014/1

          For iOS you can see your logs by following this:

          https://blog.nraboy.com/2015/1

          Best,

  7. Thank for this nice Example:-) How can I make a filtered (different Channels) replication? For example in this method:
    replicate: function(source, target, continuous) {
    return this.makeRequest(\”POST\”, this.databaseUrl + \”_replicate\”, {}, {source: source, target: target, continuous: continuous});
    },
    Exist a method for filtered Recplication? thank your help

    1. James Nocentini November 5, 2015 at 9:22 pm

      Would you like to filter based on the user that is being authenticated or as a guest user (i.e. unauthenticated)? You can create users and then grant a user access to a set of channels. In that case you would specify a cookie session in the request body of the _replicate method. Or you could say to the replicator to only pull documents from a particular channel. See the _replicate api reference for an example on using the cookie session http://developer.couchbase.com
      It\’s missing explanations on how to specify channel names though. I\’ll have a look and let you know.

      1. Thank you for your fast reply. That would be nice if you can you do that. I want to pull the documents as guest user.
        In the documents there is a field for the channels .. channels:[\”user123\”, \”user1234\”]…..So the Url have to look this?
        http://sync.couchbasecloud.com… . to get only the docs from channel user123. I have also another question, can i get the progress of the pull or an information when it is finished?

        1. The URL you pasted above would get the documents from Sync Gateway directly. You could also instruct the replicator to only pull documents from a specific channel with the following request body in the POST /_replicate (here, the replicator will pull document from the nyc channel only:
          {
          \”query_params\”: {
          \”channels\”: \”nyc\”
          },
          \”filter\”: \”sync_gateway/bychannel\”,
          \”source\”: {
          \”url\”: \”http://localhost:4984/sg-test/\”
          },
          \”target\”: {
          \”url\”: \”cblite-test\”
          }
          }

          For the progress information, there is an /_active_tasks endpoint for that http://developer.couchbase.com

          1. thanks:-)

          2. Hi James, i have one more question to the Sync by Channel:

            The Server Doc looks like this:

            {
            \”click\”: \”to edit\”,
            \”new in 2.0\”: \”there are no reserved field names\”,
            \”channels\”: [\”nyc\”]
            }

            Is this correct that i have to extend the ng-couchbase-lite.js library. I have extended this method:

            replicate: function(query_params, filter, source, target, continuous) {

            return this.makeRequest(\”POST\”, this.databaseUrl + \”_replicate\”, {}, {query_params:query_params, filter:filter, source: source, target: target, continuous: continuous});

            },

            This is my replicate Call:

            Database.replicate({\”channels\”: [\”nyc\”]}, \”sync_gateway/bychannel\” , dbName, \”http://104.155.79.21:4984/bucket_db_sync\”, true).then(function(result) {
            console.log(result);
            Database.replicate({\”channels\”: [\”nyc\”]}, \”sync_gateway/bychannel\” ,\”http://XXX.XXX.XXX.XXX:4984/bucket_db_sync\”, dbName, true).then(function(result) {
            console.log(result);
            }, function(error) {
            console.log(\”ERROR DEVICE SYNC-> \” + JSON.stringify(error));
            });

            It doesnt\’t work i get an error:

            WARNING: CBL_Pusher[http://XXX.XXX.XXX.XXX:4984/monitoring_sync]: No filter \’sync_gateway/bychannel\’ (err 404)

            Is there an better way, that i don\’t have to extend the ng-couchbase-lite.js library?

            Thank you for your answer.

          3. If you want to specify multiple channels, you should comma-separate them in a string like this:

            {
            \”query_params\”: {
            \”channels\”: \”nyc,london\”
            },
            \”filter\”: \”sync_gateway/bychannel\”,
            \”source\”: {
            \”url\”: \”http://localhost:4984/sg-test/\”
            },
            \”target\”: {
            \”url\”: \”cblite-test\”
            }
            }

            Does it work if you change [\”nyc\”] to \”nyc\”? Yes you\’ll need to change the replicate api call or create a new one.

  8. Hi Nic, Could you please give examples of how one would add an attachment to the document and then get it back later. How would one refer to the attachment with a field in the document.

    Thanks!

    1. Sounds like a perfect idea for another blog tutorial πŸ™‚

  9. hey i m new couchbase db with node js .please tell me how can i create databse on couchdb server thenn how can i perform CURD opertaion on this.

    1. You might want to check out my CEAN stack tutorial:

      https://blog.nraboy.com/2015/1

      Replace the AngularJS (A) to a mobile platform if that\’s what you prefer.

      Best,

  10. Thanks for the tutorial Nic..

    My project builds fine without the plugin installed but after installing plugin build fails with following error…

    cordova version : 5.4.1
    Ionic Version : 1.7.10

    1. Looks like you are suffering from what I mentioned in this section:

      Solving Any Gradle Dependency Problems

      Can you confirm that you\’ve followed those instructions correctly?

      Best,

      1. Thanks.. That made it work.. πŸ™‚

  11. Hi! My friend and I are trying to make this works but everytime we get \”Couchbase Lite is not installed\”.
    We have followed your guide step by step but we still get the error.
    We have also tried to download the source code from the couchbaselabs\’ github repository but the error is the same!

    What are we missing??
    Thanks a lot for any help you can give us.

    1. Can you confirm you are not trying to use ionic serve, ionic view, or ionic build? Can you also confirm you are not trying to test via a web browser? I ask because none of what I mentioned will work. You need to compile and install to the device or simulator.

      Best,

      1. I was trying to use ionic serve and also the app installed on my android device.

        Why can\’t I use ionic serve or ionic view?

        Thanks

        1. Ionic serve and ionic view are alpha and in my experience have very poor compatibility with plugins.

          Best,

      2. I am getting this error also. And I am not sure how to tell if I am using ionic serve, ionic view, or ionic build?

        1. Walk me through the steps on how you test your application. Don\’t skip anything. Please include commands as well.

          Best,

          1. I had the same problem too. I solved it by removing my platform, in this case, android, and add again. I seems the problem occurs when add platform before to add the couche base plugin.

          2. Yea sometimes Apache Cordova gets wacky with the order that you add things.

  12. When I run the project a second time no listeners are created as it only seems to happen when the db is created. Also, when the list is populated by the function queryView I am unable to delete items as _id is not defined.

    Could you please explain how to correct both issues?

  13. Answered my own question. Caught 412 status code when creating the database and adjusted the todo list view to include the _id value.

    Nice tutorial.

    Thanks

    1. Awesome! Glad you got it. I will be making a revision to fix 412 errors on application relaunch.

  14. Hey, I wanna ask something, I found the app working, but nothing show on app except the \”+\” button and form for input.. but the data not showing…

    1. What do your logs say?

      1. There\’s no error..

        Or might be I miss something ?

        1. What platform are you using and how are you checking?

          1. i using android platform and check with google chrome

            may i ask something ? what sintax to show the data ?

          2. You\’ll want to check your logs via ADB, not Chrome. You can read the following for more information:

            https://blog.nraboy.com/2014/1

            When you have your logs, please paste them in the comments so I can take a look.

            Best,

          3. Hello, might be i have miss something..

            I confused were i must put this sintax…

          4. Yes, that is how you query the view that you created. It goes in your controller.

          5. I have put the script on my controller, but when i check it with chrome, it\’s show this error

            Note :
            – when i check on the \”ng-couchbase-lite.min.js\”, there is a function \”queryView\”, but I can\’t called on the app.js
            – I already add the \”ng-couchbase-lite.min.js\” above the \”app.js\”, but, this error still come and I can\’t run the program

          6. This plugin uses native code so you cannot test in a web browser.

          7. I\’m running on the android and inspect element on chrome using USB Debugging

          8. Sounds like \’todoDatabase\’ is null then. Are you sure you defined it and made it global?

          9. This is global variable right ?

          10. Yes, can you confirm that it is loaded inside your module.run method?

          11. Yes, take a look on the picture

            Is that right ?

          12. Yes but can you confirm that it was actually loaded? Is the controller making the query the first controller that loads after the module.run? If yes, it is probably a race condition. Opening the database and setting up the views is asynchronous.

          13. How to confirm it ??

            I\’m sorry to asking something like this, I\’m still newbie πŸ™‚

          14. Print out the variable after you define it and see if it is null.

          15. After i print out the \”todoDatabase\”, and, you\’re right. It says \”null\”

            how to fix that ?

          16. Which one are you printing? I assume you\’re doing the following:

            Correct?

          17. I https://uploads.disquscdn.com/… \’m sorry for the late reply..

            here I put the console.log ( I put it after the \”if(!window.cblite)\” close tag)

          18. That\’s not correct since the getURL is asynchronous. It may, and probably hasn\’t, completed the initialization process.

          19. Ok, i will try to console.log just like you say before ?

          20. This is the result of the console.log

            *I put after this code \”todoDatabase = new $couchbase(url, \”todo\”);\”

            https://uploads.disquscdn.com/

          21. Yes so it was loaded. You\’re suffering from a race condition somewhere (trying to use the library before it has been loaded fully). Being that AngularJS and this plugin is asynchronous, you have to follow the rules of the design.

            I encourage you to double check your code, or clone the project from GitHub.

            Best,

  15. Sriram Madduri March 1, 2016 at 4:06 pm

    hi
    i am getting queryView of null error

  16. Hi Nic,
    nice tutorial thanks for this, but i have one query can i create view as per my requirement not on app load.

    1. Yes you can do that.

      Also, in case it isn\’t clear, you only have to create a view once. Once it is created, it is saved within your local database and can be queried at any time after.

      Best,

      1. Hey Nic,
        thanks for reply.
        i create one view on app load and that view is working correctly, but then i tried to create another view in my controller (not on app load) to calling below mentioned function

        $scope.createview = function() {
        var todoViews = {
        tasks: {
        map: function(doc) {
        if(doc.firstname==\”Chandan\” ) {
        emit(doc._id, {firstname: doc.firstname, lastname: doc.lastname, email: doc.email, rev: doc._rev})
        }
        }.toString()
        }
        };
        todoDatabase.createDesignDocument(\”_design/todo\”, todoViews);
        todoDatabase.listen();
        };

        but it returning below mentioned error:-
        PUT http://ad92e99d-385a-46b7-9358-5fcb44944091:40c43d4d-9fb0-484f-ba78-082bacb2208d@localhost:5984/todo/_design/todo 409 (Conflict)

        please lookout.

        1. You should create all views for a given design document at the same time. You are getting that conflict because _design/todo already exists.

          1. Hi Nic,
            Thanks for this, it worked for me.
            but i have one more query, why we are passing this below map function as .toString().

            map: function(doc) {
            if(doc.firstname==\”Chandan\” ) {
            emit(doc._id, {firstname: doc.firstname, lastname: doc.lastname, email: doc.email, rev: doc._rev})
            }
            }.toString()

            because of this when i trying to do
            var username=\”chandan\”;

            if(doc.firstname == username ) {
            emit(doc._id, {firstname: doc.firstname, lastname: doc.lastname, email: doc.email, rev: doc._rev})
            }
            }.toString() it does n\’t fetch my data.

          2. You might want to read this to build up your understanding of MapReduce Views:

            http://docs.couchbase.com/admi

            Best,

  17. Hi Nic, I am newbie with Couchbase, I followed your tutorial but when run in device the log show the error 412 :
    Failed to load resource: the server responded with a status of 412 (Precondition failed) http://b24781df-87c6-4f08-a5a0-79a98c045265:174400da-d82c-48b4-bd70-05587e0e2fd2@localhost:598
    I know that need to create the todo database in couchbase server, but don\’t know how to get url and plugin to code. Can you help me with this ? Thanks

    1. Did you look at post 2 in the series? In that one I focus on sync. Post 1 is only local stuff.

  18. I built the app for android platform, but the app is blank. I even downloaded whole code and built the app for android platform but the app only shows guest login button and clicking on it doesn\’t do anything.

    1. What do your logs say?

      1. I don\’t know how to view the logs, I installed the app on a physical device, not an emulator.

      2. \”TypeError: Cannot call method \’queryView\’ of null

      3. \”TypeError: Cannot call method \’queryView\’ of null

  19. Sorry to post a new comment, but I think the reply wasn\’t getting posted.
    The log says: \”TypeError: Cannot call method \’queryView\’ of null

    1. It means todoDatabase did not get set. Can you check in the run method to make sure that it is being set? I mean check via adding some console outputs.

      1. Yeah I got it working, thanx for the help.

  20. […] year I wrote about using Couchbase Mobile in an Ionic Framework mobile application. Back then we were using Ionic Framework 1.0 and AngularJS 1.0. Technology has changed over the […]

  21. […] I wrote about how to use Couchbase in an Ionic Framework mobile Android and iOS application, but it made use of Couchbase Lite as its embedded NoSQL database. This time around we’re […]

Leave a reply