0

I don't get when I call the let item = stationData[0] it says that its index is out of range... But inside my Alamofire request it returns that it has data...

Below is my code.

my alamofire is inside the viewdid load.

        Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default).responseJSON {
                responseData in
        
        if responseData.result.value != nil {
            let swiftyJson = JSON(responseData.result.value as Any)
            if let data = swiftyJson["data"].arrayObject as? [[String: Any]] {
                if data.isEmpty{
                    print("NO DATA FOUND")
                }
                else {
                    self.stationData = data.map(StationData.init)
                }
            }
        }
      }

Here is my code where I use stationData

extension ParameterViewController: UICollectionViewDataSource {

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    switch itemType {
    case .items:
        return parameterName1.count
    case .items1:
        return parameterName2.count
    case .items2:
        return parameterName3.count
    default:
        print("No count to get")
    }
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ValuesViewCell", for: indexPath) as! ValuesViewCell

    let item = stationData[0]

    switch itemType {
    case .items:
        cell.setData(parameterName: self.parameterName1[indexPath.row], parameterValue: item.vakue1)
    case .items1:
        
        cell.setData(parameterName: self.parameterName2[indexPath.row], parameterValue: item.value2)
    case .items2:

        cell.setData(parameterName: self.parameterName3[indexPath.row], parameterValue: item.value3)
    default:
       print("No cell to insert")
    }
    return cell
}

}

Charles
  • 13
  • 7
  • You are making an asynchronous call and are trying to access the data before it has arrived. Does this answer your question? [Returning data from async call in Swift function](https://stackoverflow.com/questions/25203556/returning-data-from-async-call-in-swift-function) – Joakim Danielson Sep 11 '20 at 05:47
  • Yes actually already thought of that but I cant find a way how to lets the data arrive first before I call it... – Charles Sep 11 '20 at 06:00

1 Answers1

0

You should not access array directly by index if your array is not ready at the time of loading.

Instead of using

let item = stationData[0]

Try something like this

guard let item = stationData.first else { 
    return emptyCell
}

With this, you will always check if your array has the element.

Also you need to refresh the tableView when your data is ready from Alamofire. Try this when you set stationData

else { 
   self.stationData = data.map(StationData.init)
   self.tableView.reloadData()
}

Now, when your data is ready, tableView will reload and it will return proper cell with stationData's first element.

Serhat
  • 76
  • 6
  • This worked for me.... I would like to know in the part stationData.first part can I change it where I can pass a specific number? Thanks – Charles Sep 11 '20 at 06:45
  • @Charles You can check it's `count` before passing a specific number to ensure it does hold value at that index – Tj3n Sep 11 '20 at 07:03
  • can you do it like this? `guard let item = stationData[3] else { return emptyCell }` – Charles Sep 14 '20 at 09:03