简体   繁体   中英

Cannot append data to array from GET request

I am trying to load data from a GET request using Alamofire library in swift and cannot append data from the requests. I am trying to populate an array of orders to load into a UITableView.

I have tried a few various ways of solving this issue but nothing is working for me. I have commented out the method I tried because with 2 separate calls to fetchAll...Orders and the second call always overwrites the first and then the tableView is loaded with missing items.

class DrinkOrdersTableViewController: UITableViewController {

    var orders: [Order] = []

    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.title = "Current Orders"

    }

    override func viewWillAppear(_ animated: Bool) {

//        fetchAllBeerOrders { orders in
//            self.orders = orders!
//            //print("Beer fetch: ", self.orders)
//            self.tableView.reloadData()
//        }

//        fetchAllCocktailOrders { orders in
//            self.orders = orders!
//            //print("Cocktail fetch: ", self.orders)
//            self.tableView.reloadData()
//        }

        fetchAllBeerOrders { orders in
            self.orders.append(orders)
            self.tableView.reloadData()
        }

        fetchAllCocktailOrders { orders in
            self.orders.append(orders)
            self.tableView.reloadData()
        }

    }

    private func fetchAllCocktailOrders(completion: @escaping([Order]?) -> Void) {
        Alamofire.request("http://127.0.0.1:4000/orders", method: .get)
            .validate()
            .responseJSON { response in
                guard response.result.isSuccess else { return completion(nil) }
                guard let rawInventory = response.result.value as? [[String: Any]?] else { return completion(nil) }
                let currentOrders = rawInventory.compactMap { ordersDict -> Order? in
                    guard let orderId = ordersDict!["id"] as? String,
                        let orderStatus = ordersDict!["status"] as? String,
                        var pizza = ordersDict!["cocktail"] as? [String: Any] else { return nil }
                    pizza["image"] = UIImage(named: pizza["image"] as! String)

                    return Order(
                        id: orderId,
                        pizza: Pizza(data: pizza),
                        status: OrderStatus(rawValue: orderStatus)!
                    )

                }
                completion(currentOrders)
        }

    }

    private func fetchAllBeerOrders(completion: @escaping([Order]?) -> Void) {
        Alamofire.request("http://127.0.0.1:4000/orders", method: .get)
            .validate()
            .responseJSON { response in
                guard response.result.isSuccess else { return completion(nil) }
                guard let rawInventory = response.result.value as? [[String: Any]?] else { return completion(nil) }
                let currentOrders = rawInventory.compactMap { ordersDict -> Order? in
                    guard let orderId = ordersDict!["id"] as? String,
                        let orderStatus = ordersDict!["status"] as? String,
                        var pizza = ordersDict!["pizza"] as? [String: Any] else { return nil }
                    pizza["image"] = UIImage(named: pizza["image"] as! String)

                    return Order(
                        id: orderId,
                        pizza: Pizza(data: pizza),
                        status: OrderStatus(rawValue: orderStatus)!
                    )

                }
                completion(currentOrders)
        }
    }

As of right now I am getting this error with code above: Cannot convert value of type '[Order]?' to expected argument type 'Order' Cannot convert value of type '[Order]?' to expected argument type 'Order' . The ideal outcome of this code is to have the data that is gathered from each GET request to append to the array of Orders. I have verified that the GET requests are working and giving back the correct data. Please Help :]

You declared orders of type [Order] and your fetch methods compilation blocks return [Order]? . As you can see, you cannot convert value of type [Order]? to expected argument type Order when you wrote self.orders.append(orders) .

To fix these, put a guard unwrap in fetch method invocations.

fetchAllBeerOrders { orders in
    guard let _orders = orders else { return }

    self.orders.append(_orders)
    self.tableView.reloadData()
}

fetchAllCocktailOrders { orders in
    guard let _orders = orders else { return }

    self.orders.append(_orders)
    self.tableView.reloadData()
}

Now, you have a potential memory leak in your code. fetchAllBeerOrders and fetchAllCocktailOrders are async methods with compilation blocks. You cannot use a strong reference to self here. Use weak to avoid a memory leak, like:

fetchAllBeerOrders { [weak self] orders in
    guard let _orders = orders else { return }

    self?.orders.append(_orders)
    self?.tableView.reloadData()
}

fetchAllCocktailOrders { [weak self] orders in
    guard let _orders = orders else { return }

    self?.orders.append(_orders)
    self?.tableView.reloadData()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM