Support Topics Documentation Slack YouTube Blog

Saving array


(Jorgen Andreasson) #1

I have an object FDWeek, which in turn has an array of FDDays (7). I’m trying to save the week and its days, but end up with only the week and nothing in the FDDay table.

I use this code to create the week and days;

func createFDWeek(start: Date, member: BackendlessUser) -> Void {
    let week = FDWeek()
    let stringDate = start.stringFromDate(format: "yyyy-MM-dd 00:00:00")
    week.startDate = Utils.dateFromString(stringDate, format: "yyyy-MM-dd 00:00:00")
    week.days = [FDDay]()
    
    for i in 0...6 {
        let day = FDDay()
        day.diaryDate = Utils.addDaysToDate(week.startDate!, daysToAdd: Double(i))            
        week.days.append(day)
        print("Date: \(String(describing: day.diaryDate!.stringFromDate(format: "yyyy-MM-dd HH:mm")))")
    }
    week.saveToServer()
}

If I check the wee before saving, it looks OK with its 7 day object in the array.
Here is the code for saving the week.

   func saveToServer() {

    let dataStore = Backendless.sharedInstance().data.of(FDWeek.ofClass())
    
    dataStore?.save(
        self,
        response: { (result: Any?) -> Void in
            let obj = result as! FDWeek
            debugPrint("Food Diary Week has been saved: \(obj.objectId!)")
            NotificationCenter.default.post(name: NSNotification.Name(rawValue: "dataSaved"), object: nil)
        },
        error: { (fault: Fault?) -> Void in
            debugPrint("Server reported an error: \(fault!)")
    })
}

Somewhere I need to tell the week which member it belongs to, as well. (week.user can’t be set)


(Olha Danylova) #2

Hello,
You should save the days using the relations API.

Firstly, create the parent object (FDWeek) and save it:

let fdWeek = fdWeek()
let weekDataStore = Backendless.sharedInstance().data.of(FDWeek.self)
weekDataStore.save(dfWeek...)

Secondly, create all 7 FDDays of the week:

var daysArray = [FDDay]()
for i in 0...6 {
    let day = FDDay()
    day.diaryDate = Utils.addDaysToDate(week.startDate!, daysToAdd: Double(i))            
    daysArray.append(day)
}
let dayDataStore = Backendless.sharedInstance().data.of(FDDay.self)
dayDataStore.createBulk(daysArray...)

The result of the bulkCreate operation is the array of the saved days objectIds.
Now you can set the relation between days and week

weekDataStore?.setRelation("days:FDDay:n", parentObjectId: YOUR-SAVED-WEEK-OBJECT-ID, childObjects: ARRAY-OF-DAYS-OBJECT-IDS, response: ((NSNumber?) -> Void) responseBlock, error: ((Fault?) -> Void) errorBlock)

Regards,
Olga


(Jorgen Andreasson) #3

Thanks Olga,
I will have a go at that later.


(Jorgen Andreasson) #4

Still struggling with this.
The days save nicely, thanks Olga. But I’m having problem with relating the week to the user.
As you can see, the user is entered as ‘member’ in the function.
I’ve tried a few variations, but nothing make OwnerId show up in FDWeek, or under Users.

func createFDWeek(start: Date, member: BackendlessUser) -> Void {
    let week = FDWeek()
    let formatter = DateFormatter()
    formatter.timeZone = TimeZone(abbreviation: "UTC")
    let stringDate = start.stringFromDate(format: "yyyy-MM-dd")
    formatter.dateFormat = "yyyy-MM-dd 00:00:00"
    week.startDate = formatter.date(from: stringDate)
    week.user = member
    week.days = [FDDay]()
    let weekStore = Backendless.sharedInstance().data.of(FDWeek.self)
    weekStore?.save(
        week,
        response: { (result: Any?) -> Void in
            let obj = result as! FDWeek
            debugPrint("Food Diary Week has been saved: \(obj.objectId!)")
            
            // set relationship with member
            let userStore = Backendless.sharedInstance()?.data.ofTable("Users")
            userStore?.setRelation("users:FDWeek:1", parentObjectId: member.objectId! as String, childObjects: [obj.objectId!], response: { (result) in
                debugPrint("result: \(result)")
            }, error:{ (fault: Fault?) -> Void in
                debugPrint("Server reported an error: \(fault!)")
            })
            
            
            for i in 0...6 {
                let day = FDDay()
                day.diaryDate = Utils.addDaysToDate(week.startDate!, daysToAdd: Double(i))
                week.days.append(day)
            }
            let dayDataStore = Backendless.sharedInstance().data.of(FDDay.self)
            dayDataStore?.createBulk(week.days, response: { (Ids) in
                debugPrint("week: \(obj.objectId!)")
                debugPrint("days: \(Ids!)")
                
                
                weekStore?.setRelation("days:FDDay:n", parentObjectId: obj.objectId!, childObjects: Ids!, response: { (result) in
                    debugPrint("result: \(result)")
                }, error:{ (fault: Fault?) -> Void in
                    debugPrint("Server reported an error: \(fault!)")
                })
            },  error: { (fault: Fault?) -> Void in
                debugPrint("Server reported an error: \(fault!)")
            })
    },
        error: { (fault: Fault?) -> Void in
            debugPrint("Server reported an error: \(fault!)")
    })
}

Would really appreciate any pointers.
Jörgen


(Olha Danylova) #5

Hello Jorgen,

The ownerId property is objectId of the current (logged in) user. This property fills automatically when you’re saving object when logged in.

This line is incorrect - you can set these properties only using relations.

week.user = member

I’m a little confused - do you need no fill the ownerId property of the FDWeek objects, or set the relations from FDWeek to User object?

Here is the example how to set ownerId

func createFDWeek(start: Date, member: BackendlessUser) -> Void {
        
    Backendless.sharedInstance()?.userService.login("b@b.com", password: "111", response: { loggedInUser in
            
        // here you're logged in and every saved object ownerId = loggedInUser.objectId automatically
        // e.g
            
        let week = FDWeek()
        week.days = [FDDay]()
        //...
        let weekStore = Backendless.sharedInstance().data.of(FDWeek.self)
        weekStore?.save(week, response: { savedWeek in
                
            // now savedWeek.ownerId = loggedInUser.objectId
                
            let obj = savedWeek as! FDWeek
            debugPrint("Food Diary Week has been saved: \(obj.objectId!)")
                
            // set relationship with member - OK
            let userStore = Backendless.sharedInstance()?.data.ofTable("Users")
            userStore?.setRelation("users:FDWeek:1", parentObjectId: member.objectId! as String, childObjects: [obj.objectId!], response: { (result) in
                debugPrint("result: \(result!)")
            }, error:{ (fault: Fault?) -> Void in
                debugPrint("Server reported an error: \(fault!)")
            })                
                
            for i in 0...6 {
                let day = FDDay()
                // ...
                week.days?.append(day)
            }
            let dayDataStore = Backendless.sharedInstance().data.of(FDDay.self)
            dayDataStore?.createBulk(week.days, response: { (Ids) in
                // ..
                weekStore?.setRelation("days:FDDay:n", parentObjectId: obj.objectId!, childObjects: Ids!, response: { (result) in
                    debugPrint("result: \(result)")
                }, error:{ (fault: Fault?) -> Void in
                    debugPrint("Server reported an error: \(fault!)")
                })
            },  error: { (fault: Fault?) -> Void in
                debugPrint("Server reported an error: \(fault!)")
            })
        },
                        error: { (fault: Fault?) -> Void in
                            debugPrint("Server reported an error: \(fault!)")
        })
    }, error: { fault in
        debugPrint("Server reported an error: \(fault!)")
    })
}

And here is the result:
We have the FD week object with one-to-many relations to FDDay objects (days column) and the User object (member) that has one-to-many relations to the FDDays (users column…)

Regards,
Olha


(Jorgen Andreasson) #6

Hi Olga,
Thanks for getting back.
This app is a little;e different as so far as it’s a ‘back office’ in macOS. So I don’t have a logged in user, hence I was passing the user into this function. It’s the currently selected member that I’m creating the week for.
I save the user.objectId to be able to manually set a search for the user’s weeks. Probably not the best way, but it works :slight_smile:

The week and days is only the start of the structure.
It’s a lot deeper than that;
user -> week -> day -> meal -> portion

Jörgen


(Olha Danylova) #7

Well, than you an just add the userId property in the FDWeek and put member.objectId there:
fdWeekObject.userId = member.objectId
and then. make a search using DataQueryBuilder.

Anyway, ownerId is a system property and you cannot set it manually.

Regards,
Olga