Couchbase plugin, error executing queries with existent views


#1

I am using {NS} with Angular 5
I have an Angular service called dbService which create the couchbase instance in the constructor along with some views and also have some CRUD operations methods.

@Injectable()
export class DbService {

db: Couchbase

constructor(private ) {
// create or open a database
this.db = new Couchbase(“testdb”);

    // create views, just for testing get every document
    this.db.createView('User', '1', (doc, emitter) => {
            emitter.emit(doc._id, doc);
    });

}

private unwrap(doc, docId?) {
let instance = doc.instance;
instance.id = docId ? docId : doc._id;
return instance;
}

private wrap(instance) {
    return {
        type: instance.$class,
        instance: instance
    };
}

search(entity: string) {

    return Observable.create((observer: Observer<any>) => {
        // return results
        observer.next({
            data: this.db.executeQuery(entity)
        });
    });
}

get(entity: string, id: string) {
    return Observable.create((observer: Observer<any>) => {
        // get doc
        let doc = this.db.getDocument(id);
        // return instance
        observer.next(this.unwrap(doc, id));
    });
}

insert(instance: any) {
    return Observable.create((observer: Observer<any>) => {
        // create doc
        let docId = this.db.createDocument(this.wrap(instance));
        let doc = this.db.getDocument(docId);
        // return instance
        observer.next(this.unwrap(doc, docId));
    });
}

update(instance: any) {
    return Observable.create((observer: Observer<any>) => {
        // update doc
        this.db.updateDocument(instance.id, this.wrap(instance));
        let doc = this.db.getDocument(instance.id);
        // return instance
        observer.next(this.unwrap(doc, instance.id));
    });
}

delete(instance: any) {
    return Observable.create((observer: Observer<any>) => {
        // return result of deletion
        observer.next(this.db.deleteDocument(instance.id));
    });
}

}

If i try to use the dbService.insert() method it works as expected and inserts the document into the database:

dbService.insert(userInstance);

But later when i try to do:

dbService.search(‘User’).subscribe(results => {
// TODO: do something with results
})

I am getting this error:

CONSOLE ERROR [native code]: ERROR TypeError: null is not an object (evaluating ‘resultSet.nextRow’)
CONSOLE ERROR [native code]: ERROR CONTEXT [object Object]

That running the app in ios.
I don’t where else to look because i am limited to the methods the plugin exposes from the couchbase api.

Thanks in advance.


#2

A few questions:

  • How do you know the insert truly worked? Did you try a get operation after based on the document key and it returned data?
  • What results do you get on Android? Just trying to narrow down if this is potentially an Android and iOS problem or just iOS.

Best,


#3

The insert method returns the document just created with the id assigned by the database and i logged it in the console to make sure is being inserted, i haven’t tried in android i will now and let you know.


#4

When trying to test it in android, i am using an android simulator and this is the error is giving me.

MANAGER ERROR: Cannot read property ‘AndroidContext’ of undefined

And from that point as database is null in the Couchbase instance all the other methods are failing.


#5

Now this is the error is giving me in Android when trying to do the executeQuery

ERROR Error: com.couchbase.lite.CouchbaseLiteException: getViewID() < 0, Status: 404 (HTTP 404 not_found)
JS: com.couchbase.lite.store.SQLiteViewStore.updateIndexes(SQLiteViewStore.java:250)
JS: com.couchbase.lite.View.updateIndexes(View.java:321)
JS: com.couchbase.lite.View.updateIndex(View.java:294)
JS: com.couchbase.lite.Database.queryViewNamed(Database.java:2178)
JS: com.couchbase.lite.Query.run(Query.java:446)
JS: com.tns.Runtime.callJSMethodNative(Native Method)
JS: com.tns.Runtime.dispatchCallJSMethodNative(Runtime.java:1088)
JS: com.tns.Runtime.callJSMethodImpl(Runtime.java:970)
JS: com.tns.Runtime.callJSMethod(Runtime.java:957)
JS: com.tns.Runtime.callJSMethod(Runtime.java:941)
JS: com.tns.Runtime.callJSMethod(Runtime.java:933)
JS: com.tns.gen.java.lang.Object_frnal_ts_helpers_l58_c38__ClickListenerImpl.onClick(Object_frnal_ts_helpers_l58_c38__ClickListenerImpl.java:12)
JS: android.view.View.performClick(View.java:6294)
JS: android.view.View$PerformClick.run(View.java:24770)
JS: android.os.Handler.handleCallback(Handler.java:790)
JS: android.os.Handler.dispatchMessage(Handler.java:99)
JS: android.os.Looper.loop(Looper.java:164)
JS: android.app.ActivityThread.main(ActivityThread.java:6494)
JS: java.lang.reflect.Method.invoke(Native Method)
JS: com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
JS: com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
JS: ERROR CONTEXT [object Object]


#6

Hey @rolandobermudez,

I spun up a new project on my end and checked to make sure it is using Angular 5.X and it is. I didn’t run into any issues, although I didn’t use your code.

I created a database.service.ts file within the project that contains the following:

import { Injectable } from "@angular/core";
import { Couchbase } from "nativescript-couchbase";

@Injectable()
export class DatabaseService {

    private db: any;

    public constructor() {
        this.db = new Couchbase("test-database");
        this.db.createView("people", "1", (document, emitter) => {
            emitter.emit(document._id, document);
        });
    }

    public getDatabase() {
        return this.db;
    }

}

Then I added the following code to the project’s app.module.ts file:

@NgModule({
    bootstrap: [
        AppComponent
    ],
    imports: [
        NativeScriptModule,
        AppRoutingModule
    ],
    declarations: [
        AppComponent,
        ItemsComponent,
        ItemDetailComponent
    ],
    providers: [
        DatabaseService,
        ItemService
    ],
    schemas: [
        NO_ERRORS_SCHEMA
    ]
})

More specifically note the providers array which now contains the previously created DatabaseService class.

Finally, I have the following code in the app.component.ts file:

import { Component, OnInit } from "@angular/core";
import { DatabaseService } from "./database.service";

@Component({
    selector: "ns-app",
    templateUrl: "app.component.html",
})
export class AppComponent implements OnInit {

    private database: any;

    public constructor(private data: DatabaseService) {
        this.database = data.getDatabase();
    }

    public ngOnInit() {
        this.database.createDocument({ "firstname": "Nic", "lastname": "Raboy" });
        let rows = this.database.executeQuery("people");
        for(let i = 0; i < rows.length; i++) {
            console.dir(JSON.stringify(rows[i]));
        }
    }

}

Now that code is not complex so it doesn’t do a whole lot and doesn’t make use of any XML bindings, but all I was trying to do was make sure that data was added and that queries worked without issue.

When doing tns run ios, I looked at my console and it did what I expected.

What you might want to do is the following:

  1. Update your NativeScript CLI
  2. Update Xcode and any installed simulators
  3. Wipe out the projects node_modules, hooks, and platforms directories and do a tns install to get the latest and greatest without any chance of caching issues.

If my example works, but yours continues to fail, you may want to investigate how you’re working with observables. I’m sure @jen.looper or @JoshSommer could help you with that.

Best,


#7

Thank you @nraboy for your help, while i was looking on how to fix this, i find out this other plugin called nativescript-couchbaselite which worked for me so decided to use it and now i have it working. One thing to notice is that using the previous plugin the Cocoa Pods for the couchbase lite was never installed in ios, at least i didn’t see logs of it in my terminal.


#8

Awesome, glad you got something working :slight_smile: