Home > Software design >  Value of type 'ListViewController.Pokemon' has no subscripts
Value of type 'ListViewController.Pokemon' has no subscripts

Time:09-29

I want to return Pokemon names from PokeApi, but I have this error : Value of type 'ListViewController.Pokemon' has no subscripts.

Here's my code :

import UIKit

class ListViewController: UIViewController {
    @IBOutlet weak var pokemon1: UILabel!
    @IBOutlet weak var pokemon2: UILabel!
    @IBOutlet weak var pokemon3: UILabel!
    @IBOutlet weak var pokemon4: UILabel!
    @IBOutlet weak var pokemon5: UILabel!
    
    let url = "https://pokeapi.co/api/v2/pokemon"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchData(from: url)
    }
    
    
    
    func fetchData(from url: String) {
        let url = URL(string: url)
        let defaultSession = URLSession(configuration: .default)
        let dataTask = defaultSession.dataTask(with: url!) { (data: Data?, response: URLResponse?, error: Error?) in
            if(error != nil) {
                print(String(describing: error))
                return
            }
            
            var json: Pokemon
            
            do {
                json = try JSONDecoder().decode(Pokemon.self, from: data!)
                Swift.print(json)
                
                DispatchQueue.main.async {
//                    self.pokemon1.text = json[0].name
                    self.pokemon2.text = json[1].results.name
//                    self.pokemon3.text = json[0].results.name
//                    self.pokemon4.text = json[3].name
//                    self.pokemon5.text = json[4].name
                    //callback: fonction que j'appelle à la suite d'un évènement
                }
            } catch {
                print(error)
                return
            }
        }
        dataTask.resume() // Commence la dataTask si elle n'est pas en marche actuellement
    }
    
    struct Pokemon: Codable {
        let results: [Result]
    }
    
    struct Result: Codable {
        let name: String
        let url: String
    }
}

I checked with the print and I am receiving the json data. here's what's in the print :

Pokemon(results: [RattrapageIOS.ListViewController.Result(name: "bulbasaur", url: "https://pokeapi.co/api/v2/pokemon/1/"), RattrapageIOS.ListViewController.Result(name: "ivysaur", url: "https://pokeapi.co/api/v2/pokemon/2/"), RattrapageIOS.ListViewController.Result(name: "venusaur", url: "https://pokeapi.co/api/v2/pokemon/3/"), RattrapageIOS.ListViewController.Result(name: "charmander", url: "https://pokeapi.co/api/v2/pokemon/4/"), RattrapageIOS.ListViewController.Result(name: "charmeleon", url: "https://pokeapi.co/api/v2/pokemon/5/"), RattrapageIOS.ListViewController.Result(name: "charizard", url: "https://pokeapi.co/api/v2/pokemon/6/"), RattrapageIOS.ListViewController.Result(name: "squirtle", url: "https://pokeapi.co/api/v2/pokemon/7/"), RattrapageIOS.ListViewController.Result(name: "wartortle", url: "https://pokeapi.co/api/v2/pokemon/8/"), RattrapageIOS.ListViewController.Result(name: "blastoise", url: "https://pokeapi.co/api/v2/pokemon/9/"), RattrapageIOS.ListViewController.Result(name: "caterpie", url: "https://pokeapi.co/api/v2/pokemon/10/"), RattrapageIOS.ListViewController.Result(name: "metapod", url: "https://pokeapi.co/api/v2/pokemon/11/"), RattrapageIOS.ListViewController.Result(name: "butterfree", url: "https://pokeapi.co/api/v2/pokemon/12/"), RattrapageIOS.ListViewController.Result(name: "weedle", url: "https://pokeapi.co/api/v2/pokemon/13/"), RattrapageIOS.ListViewController.Result(name: "kakuna", url: "https://pokeapi.co/api/v2/pokemon/14/"), RattrapageIOS.ListViewController.Result(name: "beedrill", url: "https://pokeapi.co/api/v2/pokemon/15/"), RattrapageIOS.ListViewController.Result(name: "pidgey", url: "https://pokeapi.co/api/v2/pokemon/16/"), RattrapageIOS.ListViewController.Result(name: "pidgeotto", url: "https://pokeapi.co/api/v2/pokemon/17/"), RattrapageIOS.ListViewController.Result(name: "pidgeot", url: "https://pokeapi.co/api/v2/pokemon/18/"), RattrapageIOS.ListViewController.Result(name: "rattata", url: "https://pokeapi.co/api/v2/pokemon/19/"), RattrapageIOS.ListViewController.Result(name: "raticate", url: "https://pokeapi.co/api/v2/pokemon/20/")])

What seems to be the issue ?

CodePudding user response:

You are trying to access the Pokemon type and get it's name, but name is a property of the Result type, instances of which are in the results array. What you want is:

json.results[0].name

to get the name of the first item in the array. If you used more informative names for your types the issue would have been more obvious. eg.

struct Wrapper: Codable {
        let results: [Pokemon]
    }
    
    struct Pokemon: Codable {
        let name: String
        let url: String
    }
}

and then you'd need

let wrapped = try JSONDecoder().decode(Wrapper.self, from: data!)
let pokemons = wrapped.results

//etc

self.pokemon2.text = pokemons[0].name


  • Related