-2

So, I have a json get request which gets all horse objects of class Horse. This works successfully. I have a completion handler which is supposed to let me use the horses object again in another view where I call the getHorses request but when I try to get those objects into another array it does not append them. Why is that the case?

Here is my code:

func getJSONHorses (completion: @escaping ([Horse])->[Horse]) { //Message<[Horse]>
          let url = "http://localhost:8083/horses"
      if let url = URL(string: url)
      {
          let task = session.dataTask(with: url) { data, response, error in

                    if error != nil || data == nil {
                        print("Client error!")
                        return
                    }
              let str = String(decoding: data!, as: UTF8.self)
              print(str)
                    do {
                     print("nothing")

                      let json = try JSONDecoder().decode(Message<[Horse]>.self, from: data!)

                        print(json.model?.count as Any)
                     // print(json.model as Horse)
                    //  print(json.self.model)
                    //  print(json.model)

                      print(json.model as Any)
                      print("something")
                        completion(json.model!)


                    } catch {
                        print("JSON error: \(error)")
                      print("erroooorrrrrr")
                    }
                }

                task.resume()
          print("finished")

      }
  }

Here I use the function:

print("Startttt")
    backEnd.getJSONHorses(completion:{(horse) in
            for h in horse {
                self.horses.append(h)
            }
        print(horse.count)
           self.horses = horse
            //print(horse.count as Any
            return horse
        })

    print(horses.count)
    print("END")

THe horses array is 0 even when I try to append the horses to it.

Tator
  • 125
  • 1
  • 7
  • 2
    You print `horses.count` *before* the completion handler is called ... – Martin R Jan 22 '20 at 14:01
  • The horses haven't been fetched when the second `print(horses.count)` is run. Just delete the second print statement, because you already have one inside the completion handler. – Sweeper Jan 22 '20 at 14:02
  • Yes, but how do I fetch them properly so I can display them in a table. Currently, the don't get displayed. Even the first print(horses.count )does not display in the terminal – Tator Jan 22 '20 at 14:05
  • @MartinR We really need to figure out some cannonicle way to answer questions like these. The description of the problem is simple, the prescription of the solution is really difficult. It's hard to answer questions that delve into architecture. – Alexander Jan 22 '20 at 14:08
  • 1
    I am fairly sure that some *“reload the table view after the data has been fetched asynchronously”* have already been given. – Martin R Jan 22 '20 at 14:18

1 Answers1

1

I've tested your code with previous data (JSON and implementation) and first of all, I'd recommend use this:

func getJSONHorses(completion: @escaping([Horse]) -> Void)

you should prepare you logic for UITableViewDelegate, UITableViewDataSource (tableView depends on your array and you set numberOfRowsInSection like self.horses.count and etc.) and set your data for tableView in some variable (as you did - self.horses where it is global var horses = [Horse]()) and just call this:

backEnd.getJSONHorses(completion:{ horse in
    print(horse.count)
    self.horses = horse
    self.tableView.reload()
})

that's all. I've checked and it's enough. And be careful - you should reload the table after receiving the data

Vadim Nikolaev
  • 2,132
  • 17
  • 34