1

I have next structure:

  1. Invoice class.
  2. Invoice contains Array of InvoiceEmployee pointers
  3. InvoiceEmployee contains array of InvoiceItem objects
for employeeDataSet in someDataSet { 

for viewModelData in someDataSet { 
let pfInvoiceItem = PFObject(className: "InvoiceItem")
pfInvoiceItem.setValue(viewModelData.customerRate, forKey: "customerRate")
pfInvoiceItem.setValue(viewModelData.customerHours, forKey: "customerHours")
pfInvoiceItem.setValue(viewModelData.total, forKey: "total")
invoiceItems.append(pfInvoiceItem)
}


let pfInvoiceEmployee = PFObject(className: "InvoiceEmployee")
pfInvoiceEmployee.setValue(employeeDataSet.username, forKey: "username")
pfInvoiceEmployee.setValue(employeeDataSet.projectEmployee, forKey: "projectEmployee")
pfInvoiceEmployee.setValue(invoiceItems, forKey: "invoiceItems")

I am getting this error

Pointer to an unsaved object. (Code: 106, Version: 1.19.1)

On this save action:

func createInvoice(with invoice: Invoice, completion: @escaping (Result<Bool, NSError>) -> ()) {
        
        guard let payPeriod = invoice.payPeriod?.getPFPayPeriod(),
              let project = invoice.project?.getPFProject() else {
            let error = NSError(domain: "OURTEAM", code: 0, userInfo: [NSLocalizedDescriptionKey: "Save invoice failure"])
            completion(.failure(error))
            return
        }
        
        
        let parseObject = PFObject(className:"Invoice")
        parseObject["project"] = project
        parseObject["payPeriod"] = payPeriod
        parseObject["title"] = "Some"
        parseObject["total"] = invoice.total
        parseObject["invoiceEmployees"] = invoice.getPFInvoiceEmployees()

        parseObject.saveInBackground {
          (success: Bool, error: Error?) in
          if (success) {
            completion(.success(true))
          } else {
            let error = NSError(domain: "OURTEAM", code: 0, userInfo: [NSLocalizedDescriptionKey: "Create invoice failure"])
            completion(.failure(error))
          }
        }
    }

But when I am looking to admin panel I can see that all record are saved properly. Meaning that InvoiceItem records got all objectIds and needed columns are set with values. The same fo InvoiceEmployee records and Invoice record in databse.

Also parseObject.saveInBackground returns success.

One thing to know that I have not saved InvoiceItem and InvoiceEmployee previously before I saved Invoice.

Usually I work with joint class and there is no such issue as I can save objects separately. Now I wold like to save invoice on demand (when all local records are fulfilled by user).

I guess could be a solution to create Invoice first of all and then add all needed data to it. But it means that I need to wait for accomplishment all callbacks related to adding employees and their items to the Invoice and if user cancel creation of invoice then I need to remove a record in database, which is a bit overloaded flow.

Matrosov Oleksandr
  • 25,505
  • 44
  • 151
  • 277
  • if saveInBackground returns success, where are you getting the error then? – Tanzim Chowdhury Feb 09 '21 at 04:33
  • I guess the problem happens because it is an array (and not a pointer or relation). In this case I believe you will have to first save the pointers and then save the main object. Another option could be sending all the data to a cloud code function to perform the operation. – Davi Macêdo Feb 09 '21 at 04:34
  • Sorry for confusion. it is not callback error it is a log message. Looks like back4app handles creating pointers if needed somehow. I checked tables and all records were created all relationship were assigned. Maybe this is just a warning and I don't need to do anything with it. – Matrosov Oleksandr Feb 10 '21 at 10:04

0 Answers0