Reputation: 245
How can I init a struct that contains an array of another struct?
I want to create an Invoice entry with all properties and items having an array of InvoiceItem.
Also, items can be null when invoice is still a draft.
Reading the JSON response from the server with invoice data and items works fine.
On the save action of the viewcontroller I have:
var invoice: Invoice?
var client: Client?
var invoiceItems : [InvoiceItem] = [InvoiceItem]()
@IBAction func saveInvoice(_ sender: Any) {
...
invoice = Invoice(invoice_id: invoice?.invoice_id, client_id: client_id, tax: 0.00, date_issue: dateIssue, due_date: dueDate,
amount_paid: 0.00,
date_transaction: "0000-00-00",
voided: 0,
note: "",
invoice_number: "",
status: "",
items: invoiceItems
)
override func viewDidLoad() {
...
invoiceItems = (invoice?.items)!
...
}
I get this error: Cannot convert value of type '[InvoiceItem]' to expected argument type 'InvoiceItem', on line: items: invoiceItems
struct InvoiceItem: Codable {
var invoice_detail_id: Int!
let description: String!
let unit_price: Decimal!
let quantity: Decimal!
init(invoice_detail_id: Int! = nil, description: String, unit_price: Decimal, quantity: Decimal) {
self.invoice_detail_id = invoice_detail_id
self.description = description
self.unit_price = unit_price
self.quantity = quantity
}
}
struct Invoice: Codable {
var invoice_id: Int!
let client_id: Int!
let tax: Decimal!
let date_issue: String!
let due_date: String!
let amount_paid: Decimal!
let date_transaction: String!
let voided: Int!
let note: String!
let invoice_number: String!
let status: String!
let items: [InvoiceItem]!
init(invoice_id: Int! = nil, client_id: Int! = nil,tax: Decimal, date_issue: String, due_date: String, amount_paid: Decimal, date_transaction: String, voided: Int, note: String, invoice_number: String, status: String, items: InvoiceItem) {
self.invoice_id = invoice_id
self.client_id = client_id
self.tax = tax
self.date_issue = date_issue
self.due_date = due_date
self.amount_paid = amount_paid
self.date_transaction = date_transaction
self.voided = voided
self.note = note
self.invoice_number = invoice_number
self.status = status
self.items = [items]
}
}
Upvotes: 1
Views: 1500
Reputation: 986
Your invoice init has items: InvoiceItem
as a parameter. The type of items is an InvoiceItem
, not an array of InvoiceItem
.
Change the type to an array of InvoiceItem
.
EDIT:
In your Invoice init you have:
self.items = [items]
You were trying to pass in an array of InvoiceItem
into a parameter defined as items: InvoiceItem
.
That obviously won't work, so I told you to change the parameter type to an array of InvoiceItem
.
Now that you have, you are wrapping your array of InvoiceItem
in array. So you have an array of an array of InvoiceItem
.
Change that line of code to:
self.items = items
Upvotes: 2
Reputation: 26026
Let's name the method with explicit names, and add one, because you are mixing array and unique object.
I'd suggest:
init(invoice_id: ... status: String, anItem: InvoiceItem)
{
...
self.items = [anItem]
}
init(invoice_id: ... status: String, multipleItems: [InvoiceItem])
{
...
self.items = multipleItems
}
In your code, since it's var invoiceItems : [InvoiceItem] = [InvoiceItem]()
, I'd use the second one because it's an array of InvoiceItem
.
invoice = Invoice(invoice_id: invoice?.invoice_id,
client_id: client_id,
tax: 0.00,
date_issue: dateIssue,
due_date: dueDate,
amount_paid: 0.00,
date_transaction: "0000-00-00",
voided: 0,
note: "",
invoice_number: "",
status: "",
multipleItems: invoiceItems
)
I don't know if you still want to use the first one, but just in case you can use keep. Do avoid duplicate code still between these two methods, the first one could call the second one with init(... multipleItems:[anItem])
.
Upvotes: 0