Hi,
When placing an order for e.g. 8 cupcakes in ContentView, then navigating through placing the order, when i receive the notification back from the server, it does not update the decodedOrder quantity correctly - but it reflects the right kind of cupcake..??
I have checked contentView, and I have made the binding correctly to quantity.
struct ContentView: View {
//With "State" the order is 'made' here...
@State private var order = Order()
var body: some View {
NavigationStack {
Form {
Section {
Picker("Select your cake type", selection: $order.type) {
ForEach(Order.types.indices, id: \.self) {
Text(Order.types[$0])
}
}
Stepper("Number of cakes: \(order.quantity)", value: $order.quantity, in: 3...20)
}
Section {
Toggle("Any special requests?", isOn: $order.specialRequestEnabled.animation())
if order.specialRequestEnabled {
Toggle("Add extra frosting", isOn: $order.extraFrosting)
Toggle("Add sprinkles", isOn: $order.addSprinkles)
}
}
Section {
Text("Total cost: \(order.price, format: .currency(code: order.localCurrency))")
}
Section {
NavigationLink("Delivery details") {
AddressView(order: order)
}
}
}
.navigationTitle("Cupcake Corner - Day 52")
}
}
}
I also believe the data upload is also correct. Anyone have any ideas?
struct CheckOutView: View {
var order: Order
@State private var confirmationMessage = ""
@State private var showingConfirmation = false
@State private var showingRejection = false
@State private var rejectionMessage = ""
var body: some View {
ScrollView {
VStack {
AsyncImage(url: URL(string: "https://hws.dev/img/cupcakes@3x.jpg"), scale: 3) { image in //Downloading an image from the web
image
.resizable()
.scaledToFit()
} placeholder: {
ProgressView()
}
.frame(height: 233)
Text("Your total cost is \(order.price, format: .currency(code: order.localCurrency))")
.font(.title)
Button("Place order") {
//make a task to send order to the web
Task {
await placeOrder()
}
}
.padding()
}
}
.navigationTitle("check out")
.navigationBarTitleDisplayMode(.inline)
.scrollBounceBehavior(.basedOnSize) //Bounce scroll only when contents require it...
.alert("Thank you!", isPresented: $showingConfirmation) {
Button("OK") { }
} message: {
Text(confirmationMessage)
}
.alert("Error", isPresented: $showingRejection) {
Button("OK") { }
} message: {
Text(rejectionMessage)
}
}
//uploading data
func placeOrder() async {
//Encode order to JSON
guard let encoded = try? JSONEncoder().encode(order) else {
print("Failed to encode order")
return
}
//create the url that we will send the data to
let url = URL(string: "https://reqres.in/api/cupcakes")! //ideally you want to handle if the url does not exist
var request = URLRequest(url: url)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpMethod = "POST" //We want to write/post data
//actually upload data or catch error
do {
let (data, _) = try await URLSession.shared.upload(for: request, from: encoded)
//Decode the order that we receive back from the server if it was sent
let decodedOrder = try JSONDecoder().decode(Order.self, from: data)
confirmationMessage = "Your order for \(decodedOrder.quantity) x \(Order.types[decodedOrder.type].lowercased()) cupcakes is on its way."
showingConfirmation = true
} catch {
rejectionMessage = "There was an error placing your order. please try again."
showingRejection = true
print("Check out failed: \(error.localizedDescription)")
}
}
}
Thanks.