Can not update Model/Document

108 views
Skip to first unread message

MobDev

unread,
Sep 23, 2014, 4:05:25 PM9/23/14
to mobile-c...@googlegroups.com
Hey guys, I am having trouble in updating document.

Can someone help me in understanding how updating works?
  • save on Model
  • update on Document
  • putProperties on Document

So far I have update working only if I am updating contents in do-while loop like following:

do {
        docContent = [doc.properties mutableCopy];
        [docContent setObject:[NSNumber numberWithInt:123456789] forKey:@"entry_date"];
        [docContent setObject:[NSNumber numberWithInt:987654321] forKey:@"user_id"];
        [doc putProperties:docContent error:&error];
    } while ([error.domain isEqualToString: CBLHTTPErrorDomain] && error.code == 409);

I don't want to change objects in do-while loop, am I missing anything?

model does have valid document and I am not getting any error on update.

Thank you.

MobDev

unread,
Sep 23, 2014, 4:46:05 PM9/23/14
to mobile-c...@googlegroups.com
 Tried doing following but No success..:(

do {
        [doc putProperties:[doc userProperties] error:&error];

       
    } while ([error.domain isEqualToString: CBLHTTPErrorDomain] && error.code == 409);


Why do I need to setObject in do-while?

Jens Alfke

unread,
Sep 23, 2014, 5:13:15 PM9/23/14
to mobile-c...@googlegroups.com

> On Sep 23, 2014, at 1:05 PM, MobDev <ehdev...@gmail.com> wrote:
>
> Can someone help me in understanding how updating works?
> • save on Model
> • update on Document
> • putProperties on Document

Have you read the documentation on these methods? It has examples of using them.
http://developer.couchbase.com/mobile/develop/guides/couchbase-lite/native-api/model/index.html#saving
http://developer.couchbase.com/mobile/develop/guides/couchbase-lite/native-api/document/index.html#updating

> I don't want to change objects in do-while loop, am I missing anything?

As part of a distributed system, Couchbase Lite doesn't support record locking or transactions. So a read-modify-write operation can have race conditions, if something else changes the document in between the read and the write. That's why the while loop is necessary — to retry the update if the document's been updated.

I agree that the loop is awkward. That's the reason for the -update: method, which encapsulates it for you. You just have to provide the block that updates the properties.

> model does have valid document and I am not getting any error on update.

If you've got a model, you should be updating it by calling -save:. You don't need to work with the document directly.

—Jens

Jens Alfke

unread,
Sep 23, 2014, 5:16:46 PM9/23/14
to mobile-c...@googlegroups.com

On Sep 23, 2014, at 1:46 PM, MobDev <ehdev...@gmail.com> wrote:

        [doc putProperties:[doc userProperties] error:&error];

This is a no-op. You're taking the existing document properties and saving them as the new properties without making any changes.

Maybe you're getting confused about the difference between document and model properties. A document supports updating the properties all at once, via -putProperties: or -update:. That creates a new revision. Because the all-at-once save can be awkward to use, CBLModel provides a layer above this that provides mutable state, where you can change properties one at a time and then save. It does this by storing the mutable state in the model object, and not writing anything to the document until you save.

Basically, CBLDocument isn't aware of any changes made to its CBLModel until you save them. Those are temporary changes that are just stored in the model itself.

—Jens

MobDev

unread,
Sep 23, 2014, 5:36:06 PM9/23/14
to mobile-c...@googlegroups.com
Thank you Jens,

I got how userProperties works from your second reply.

This is what I am doing.

1. Get the document using view’s then populate Model using CBLQueryRow.document

2. Update model properties
(following is the code I am using to update entryDateUTC & userId)

    NSError* error;
   
    NSLog(@"documentID : %@",_model.document.documentID);
    NSLog(@"database : %@",_model.document.database.name);
   
    _model.entryDateUTC = [NSNumber numberWithInt:555555555];
    _model.userId = [NSNumber numberWithInt:333333333];
   
    if (![_model save:&error]){
        NSLog(@"error : %@",error.description);
    }

Jens Alfke

unread,
Sep 23, 2014, 5:42:44 PM9/23/14
to mobile-c...@googlegroups.com
That looks fine. (Just FYI, it's a lot easier to create NSNumbers using the Obj-C literal syntax, e.g. @33333333.)

You may also want to look at the ToDoLite example app, which uses model objects.

—Jens

MobDev

unread,
Sep 23, 2014, 5:57:46 PM9/23/14
to mobile-c...@googlegroups.com

I did look at Todo-Lite example.

Save is not doing anything for me. I did add method willSave in Model, which is not getting called as well.

Thanks a lot.


Jens Alfke

unread,
Sep 23, 2014, 6:03:57 PM9/23/14
to mobile-c...@googlegroups.com

On Sep 23, 2014, at 2:57 PM, MobDev <ehdev...@gmail.com> wrote:

Save is not doing anything for me. I did add method willSave in Model, which is not getting called as well.

Are you sure you actually have a model, i.e. _model is not nil? How are you getting the model object from the query row?

Also, did you make sure to declare the properties as @dynamic in the @implementation?

—Jens

MobDev

unread,
Sep 23, 2014, 6:23:37 PM9/23/14
to mobile-c...@googlegroups.com

_model is not nil, using [ModelClass modelForDocument:_row.document] on query row.

I am not using @dynamic for any of the variables. is that required? do I have to registerClass:forDocumentType?

if I have nested classes do all needs to be CBModel or just the Main class(Document type class) needs to be CBModel?

Thanks a lot for your help Jens and apologies for asking too many questions. Take care.

Best Regards,

Jens Alfke

unread,
Sep 23, 2014, 6:34:00 PM9/23/14
to mobile-c...@googlegroups.com

On Sep 23, 2014, at 3:23 PM, MobDev <ehdev...@gmail.com> wrote:

I am not using @dynamic for any of the variables. is that required? 

Yes, otherwise they're just ordinary properties and not associated with the document. In the docs, there's even a red-lined "Caution!" section describing the exact mistake you made.

do I have to registerClass:forDocumentType?

Only if you want to dynamically create models of the appropriate class based on the document type. If you already know the class of model you want, you can just call [MyModelClass modelForDocument: …] and not have to register.

—Jens

MobDev

unread,
Sep 24, 2014, 4:38:29 PM9/24/14
to mobile-c...@googlegroups.com
Thanks a lot Jens.

That was so stupid of me.. I am using @dynamic now and running into another problem..

How would you handle if you have array of custom objects?

does that custom object needs to be subclass of CBLModel? reason is Tracker is document, TrackerType will never be saved as document.

Class1: Tracker : CBLModel
NSString trackerTitle
NSArray types // array of TrackerType
@dynamic *****


Class2: TrackerType : NSObject/CBLModel
NSString typeTitle
@dynamic *****


Scenario 1: TrackerType : CBLModel
@dynamic *****
Error: Invalid parameter not satisfying: _document

Scenario 2: Tracker : NSObject
Error: 500 Internal error


Any direction/comment would be helpful.

Thanks a lot.



Jens Alfke

unread,
Sep 24, 2014, 11:21:03 PM9/24/14
to mobile-c...@googlegroups.com

On Sep 24, 2014, at 1:38 PM, MobDev <ehdev...@gmail.com> wrote:

How would you handle if you have array of custom objects?

Read this:

The objects in the array should not be CBLModels, because that means they'll have to have their own documents. Instead they should be a class that implements CBLJSONEncoding, as described here:

—Jens

MobDev

unread,
Sep 25, 2014, 12:45:23 AM9/25/14
to mobile-c...@googlegroups.com

Cool, thanks a lot Jens, it would have not been possible without your help.

I am using array of NSObjects with CBLJSONEncoding. it is working fine.

Take care.

Best.
Reply all
Reply to author
Forward
0 new messages