Objects in array doubles

I have a strange thing happening to my objects in an array. Every time I save the parent object, this array doubles the objects in the array. To add to the confusion, it’s not the first array (relation) that doubles, it’s further down the line.
Object:
Week -> Day -> Meal -> Portion
There are 7 days in the week, as an array
There are 4 Meals in the day, as an array
The last array, Portion, get added by appending to the portions array on the Meal object.
However every time I save the Week object, the portions double. eg. they get added to the table.
None of the other arrays do this. e.g. the days stay as 7 and the meals are 7*4=28.
Any help would be gratefully aprecaited.


class FDWeek: BackendlessEntity {
 
 var user = Backendless.sharedInstance().userService.currentUser
 
 var startDate: NSDate = NSDate()
 var weight: Double = 0.0
 var suppPlan: String = ""
 var days: [FDDay] = []
 


class FDDay : NSObject {
 
 var diaryDate: NSDate = NSDate()
 var water: Double = 0.0
 var alcohol: Double = 0.0
 var bm: Int = 0
 var supps: Bool = false
 var training: Bool = false
 var targetP: Double = 0.0
 var targetF: Double = 0.0
 var targetC: Double = 0.0
 var targetV: Double = 0.0
 var bedTime: NSDate = NSDate()
 var wakeUpTime: NSDate = NSDate()
 var sleepQuaity: Int = 0
 var energyLevel: Int = 0
 var meals: [FDMeal] = []



class FDMeal: NSObject {
 
 var time: NSDate
 var planned: Bool
 var achieved: Bool
 var targetProtein: Double
 var targetCarb: Double
 var targetFat: Double
 var targetVeg: Double
 
 var note: String
 var photoPath: String
 
 var portions: [FDPortion] = []



class FDPortion: NSObject {
 
 var portion: String
 var portionSize: Double
 var portionType: String // F,P,C,V
 



let portion = FDPortion()
 portion.portionType = typeTF.text!
 portion.portion = nameTF.text!
 portion.portionSize = (sizeTF.text! as NSString).doubleValue
 currentMeal.portions.append(portion)










func saveToServer() {

        

        MMProgressHUD.showWithStatus("Saving")

        let dataStore = Backendless.sharedInstance().data.of(FDWeek.ofClass())

        

        dataStore.save(

            self,

            response: { (result: AnyObject!) -> Void in

                let obj = result as! FDWeek

                debugPrint("Food Diary Week has been saved: \(obj.objectId)")

                MMProgressHUD.dismissAfterDelay(0.5)

                NSNotificationCenter.defaultCenter().postNotificationName("dataSaved", object: nil)

            },

            error: { (fault: Fault!) -> Void in

                debugPrint("Server reported an error: \(fault)")

                MMProgressHUD.dismissWithError("Please try later", title: "Server Error!", afterDelay: 4)

        })

    }

Further investigation shows the following;

A. If I start out with 3 portions from the server and tap save. There are no changes.
B. If I add one portion to the 3 that is already there and save, I get 4 portions on the server.
C. If I save again I get the last portion added again, and again…

Is there a “dirty data” flag somewhere that can be accessed?

Hi Jorgen,

Backendless use objectId field to determine previously saved objects. As Portion class does not contains objectId Backendless considers it as new object each time you save parent object. Please, add property objectId to required class and try current case. This page can be useful.

Regards,

Denys

Thank for your help.
I added objectId to FDPortion, as suggested, but I am now getting an error when saving;

"Server reported an error: FAULT = ‘1000’ [Entity with the specified ID cannot be found: Id - ] <Entity with the specified ID cannot be found: Id - > "

Code for class;

class FDPortion: NSObject {
    
    var portion:        String
    var portionSize:    Double
    var portionType:    String  // F,P,C,V
    var objectId:       String
    


    
    override init() {


       portion     = ""
       portionSize = 0.0
       portionType = ""
       objectId    = ""
    }
}

Hi Jorgen,

ObjectId should not be empty string. It should be null for new entity.

Regards,

Denys

I can’t assign NSNULL to a String.

I think objectId should be declared as

var objectId: String?

This page can also be useful https://backendless.com/documentation/data/ios/data_relations_save_update.htm.

I’ve been following that one.

I still have the problem that when I have saved the week after adding a portion, if I save the week again directly I get another portion added. Would I need to reload the week to stop this happening? If I navigate out to the list of weeks and pick up the same week again and go to the same day. If I now save the week there is no added portion.

Still no joy.

Here is my saving function in FDWeek;









    func updateOnServer() -> FDWeek? {

        MMProgressHUD.showWithStatus("Saving")

        let backendless = Backendless.sharedInstance()

        var error: Fault?

        let result = backendless.data.save(self, error: &error) as? FDWeek

        if error == nil {

            debugPrint("Week is updated: \(result?.objectId)")

            MMProgressHUD.dismissAfterDelay(0.5)

            return result!

        } else {

            debugPrint("Server reported an error: \(error)")

            MMProgressHUD.dismissWithError("\(error!.message)", title: "Server Error!", afterDelay: 4)

            return nil

        }

    }

// called like this in the DayVC










self.currentWeek = self.currentWeek.updateOnServer()!

Hi Jorgen,

Please, try add objectId property to each class or just extend them from BackendlessEntity.
The thing is it is necessery to load related entities with either relation depth or autoload before updating deepest related entity.
You can retrieve FDWeek with relation depth 4, add new Portion and save the whole hierarchy again.

Regards,

Denys

I did add objectId to each class with no joy. I’ll see if it makes any difference if I extend them from the BackendlessEntity instead.

Still having problems.

I changed all object so they are extend from BackendlessEntity.

If I save the FDMeal on the meal screen, the portions get saved properly, and I can add another portion and save the meal again.
However, if I got back to the day screen and save there, which saves the FDWeek), the portion array doubles.

That means related entities are not properly loaded before updates. It could be fixed if set autoload on all columns with relations

They are set;

Week is autoloading Days, which is autoloading Meals, which is autoloading Portions

Should I load the Week after saving to server? Would that not double up the API calls?

I you save object to Backendless it will be returned with objectId field and you can update it without reloading

I’ll try that idea.

BTW, did you ever get a way of synchronise Core Data from iOS? It might be an easier way of doing what I’m trying to do. That way the Core Data would be the local store and only update Backendless when needed.

Such feature are in our todo-list but it is hard to predict when it would be implemented and released