Updating object but just one property...

Hi all,
I know what your gonna say… read the manual… but really I have and I am learning soon much however I have an issue I need explained.
I want to update a single column in a class for an object but when I did it wiped everything else out and just left the now loly update and all other columns empty for that object!
so how do I create a call that says ‘hay this object update this property’. I have seen examples of this and that but nothing direct… This is what I did and maybe you can make sense of it…
//UPDATE THE NEW PRICE
Responder *responder = [Responder responder:self selResponseHandler:@selector(responseHandler:) selErrorHandler:@selector(errorHandler:)];

saleItems *editItem = [saleItems new];
NSObject *tempObject = [mySaleItemsMutableArray objectAtIndex:saleItemSellected];
NSNumber *number;
number = @([ppEditorOutlet.text intValue]);
editItem.itemPPCost = number;
editItem.objectId = [tempObject valueForKey:@“objectId”];

id<IDataStore> dataStore = [backendless.persistenceService of:[saleItems class]];
[dataStore save:editItem responder:responder];

What you’re seeing makes perfect sense… Here’s what’s going on:

    You create a brand new object: saleItems *editItem = [saleItems new];

    You assign a value in one of the object properties:
    editItem.itemPPCost = number;

    You assign objectId to your object (which is good, you want to update an existing one…):
    editItem.objectId = [tempObject valueForKey:@“objectId”];

So here what happens when you send that object to the server with the save operation:

Backendless takes your object and inspects it - it gets values for ALL properties which exist in the object, not just the one where you put the value (itemPPCost), but all of them, with the default values assigned by the program. Once it has the values for all properties of your object which includes objectId as well, it sends it to the backend. On the server side we get the collection of properties with an instruction to update it. We find the object to update by its objectId and we store ALL the properties we got from the client in the corresponding columns. As a result, since all the properties were sent with their default values (with the exception of objectId and itemPPCost), everything that was there before got wiped out.

An alternative approach would be to retrieve the object you want to update from the server, modify a property (or more than one) and then save it.

Hope this helps.

Mark

ok I ran this (so all properties filled):

//UPDATE THE NEW PRICE

    Responder *responder = [Responder responder:self selResponseHandler:@selector(responseHandler:) selErrorHandler:@selector(errorHandler:)];

    

    saleItems *editItem = [saleItems new];

    NSObject *tempObject = [mySaleItemsMutableArray objectAtIndex:saleItemSellected];

    editItem.ownerId = [tempObject valueForKey:@"ownerId"];

    editItem.itemDescription = [tempObject valueForKey:@"itemDescription"];

    editItem.soldYesNo = [tempObject valueForKey:@"soldYesNo"];

    editItem.created = [tempObject valueForKey:@"created"];

    editItem.itemURLB = [tempObject valueForKey:@"itemURLB"];

    editItem.updated = [tempObject valueForKey:@"updated"];

    editItem.itemType = [tempObject valueForKey:@"itemType"];

    NSNumber *number;

    number = @([ppEditorOutlet.text intValue]);

    editItem.itemPPCost = number;

    editItem.sellerFBURL = [tempObject valueForKey:@"sellerFBURL"];

    editItem.itemTitle = [tempObject valueForKey:@"itemTitle"];

    editItem.itemURLA = [tempObject valueForKey:@"itemURLA"];

    NSString *objectId = [tempObject valueForKey:@"objectId"];

    editItem.objectId = objectId;

    editItem.seller = backendless.userService.currentUser;

    

    id&lt;IDataStore&gt; dataStore = [backendless.persistenceService of:[saleItems class]];

    [dataStore save:editItem responder:responder];

And I now have this plus all objects are gone/wiped from the class:

http://support.backendless.com/public/attachments/355733030d782ca68921a5bb3690a98e.png&lt;/img&gt;

Didn’t you have the relation defined in Users pointing to saleItems?

no I scrubbed that as it was causing me too much of a brain freeze. I removed the columns and thus the relation. I think it didn’t like the seller reference:

editItem.seller = backendless.userService.currentUser;

Maybe I should have just used the Users objectId.

there is an object in the class table with no information bar defaults and it won’t let me remove it as its got no ID.

http://support.backendless.com/public/attachments/8044f7af8bcd127ac5a786a86fa2453b.png&lt;/img&gt;

editItem.seller = backendless.userService.currentUser;
Maybe I should have just used the Users objectId.

It depends. What is the type of the “seller” property on the server in the saleItems table? Is it relation or is it a string?

Is your class definition (in your program) in sync with the table definition on the server?

hmmm… you know what I don’t think it is. I added two columns just as an idea yesterday but haven’t implemented them in code yet. would this be a real issue?

Sorry, I do not understand what " information bar defaults" are.

The best way to proceed now is do this:

  1. Retrieve an object from the server
  2. Update ONE property
  3. Save it and see if that works.

Sorry ‘Information bar Defaults’ means that in the GUI it says I have 2 objects but when I look there is only one object with no information in the columns ‘bar the defaults assigned in the program’ but this object doesn’t have a ID nor a created date or updated date.

Its just sat there and I can’t delete it or edit it. Now when I query the class my app crashed with a uncaught exception.

I will see if I can get the fault

I think my class maybe corrupt I can’t get anything from it before my app crashes.

ok I ran this:

// ------------------

BackendlessUser *user = backendless.userService.currentUser;

NSString *usersID = user.objectId;

NSLog(@"USERS ID: %@",usersID);



Responder *responder = [Responder responder:self selResponseHandler:@selector(responseHandler:) selErrorHandler:@selector(errorHandler:)];

BackendlessDataQuery *query = [BackendlessDataQuery query];

query.whereClause = [NSString stringWithFormat:@"ownerID = \'%@\'", usersID];

id&lt;IDataStore&gt; dataStore = [backendless.persistenceService of:[saleItems class]];

[dataStore find:query responder:responder];



NSLog(@"RESPONDER: %@",responder);

// ------------------

And got this:

2016-02-19 22:21:02.580 Panda[9865:422459] java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLException: Column ‘seller.B27C2FC5-1F91-5752-FF6C-279E6D720500’ not found.

Can you see the saleItems table in console? Does the data show up there?

but I had two objects there and now they are… like… invisible…

Can you post a screeshot? Full screen please…

thats the point. In the console it says I have two items but I don’t. I have one that has NO data other than the predefined defaults of each column. I actually can’t even manually add objects.

Hi Mark,

Right I had to completely recreate the saleItems class as it was well and truly corrupted! My guess is that it didn’t like the editItem.seller = backendless.userService.currentUser; line in my code as calling the direct line to the currentUser and trying to add it to a NON-Relation set column. Now that I just hold the string value for ID it works fine.

I haven’t tried to reproduce the corruption but it is something I would suggest maybe someone looking at the logs of your DB. Maybe you can prevent a similar thing happening again to someone else.

I am in test so its fine but if this was my app meMessage and I had 7k users details there that would have been a nightmare!

Take care and have a great weekend to all your guys at Backendless!

Thank you for… well… being Backendless!