Home > Software design >  Can't call the struct in the view
Can't call the struct in the view

Time:02-20

I have a code, that should match 2 JSON files and connect all data in one struct. I'm pretty sure that It works just fine, but I have faced very strange problem. I want to make a picker:


import SwiftUI


struct CurrencyView: View {
    
    @ObservedObject var api = CurrencyViewModel()
    
    @State private var pickerSelection1 = 1
    
    var body: some View {
        Text("f")
        Picker("", selection: $pickerSelection1) {
            ForEach(0..<self.api.currencies.fullName.count) { // Error here
                let currency = api.currencies.fullName[$0] // and here
        Text(currency)
        }
    }
.id(UUID())
.labelsHidden()
.padding(.leading)
    }
}


struct CurrencyView_Previews: PreviewProvider {
    static var previews: some View {
        CurrencyView()
    }
}

It shows this error:

Value of type '[Currency]' has no member 'fullName'

I know I'm missing smth and feel stupid, because I can't understand why. Thanks for the reply!)

Adding the rest of the code:

// Model


import Foundation

struct CurrencyModel: Codable {
    var results: [String:Double]
}

struct CurrencyNewModel: Codable {
    var currencies: [String:String]
}

struct Currency: Decodable {
    let currencyCode: String
    let fullName: String
    var price: Double
} 
// View Model

import SwiftUI


class CurrencyViewModel: ObservableObject {
    
    @Published var currencies: [Currency] = []

          init() {
              fetchNewData { [self] (currency) in
                  switch currency {
                  case .success(let names):
                      print("Success")
                      DispatchQueue.main.async {
                      self.currencies = names.currencies.map {
                          Currency(currencyCode: $0.key, fullName: $0.value, price: 0)
                        }
                      }
                      fetchData { result in
                          switch result {
                          case .success(let prices):
                              print("Success")
                              
                              
                              for (index, value) in currencies.enumerated() {
                                  if let price = prices.results.first(where: { $0.key == value.currencyCode }) {
                                      DispatchQueue.main.async {
                                      currencies[index].price = price.value
                                      }
                                  }
                              }
                          case .failure(let error):
                              print(error)
                          }
                      }
                  case .failure(let error):
                      print("Error", error)
        }
    }
}
      
     
    
   
    
func fetchData(completion: @escaping (Result<CurrencyModel,Error>) -> ()) {
    guard let url = URL(string: "https://api.fastforex.io/fetch-all?from=USD&api_key=7ffe65c2ef-926f01d9e8-r7eql2") else { return }
    URLSession.shared.dataTask(with: url) { data, responce, error in
        if let error = error {
            completion(.failure(error))
            return
        }
        
        guard let safeData = data else { return }
        
        do {
            let currency = try JSONDecoder().decode(CurrencyModel.self, from: safeData)
            completion(.success(currency))
        }
        catch {
            completion(.failure(error))
        }
    }
    .resume()
    
    
    }
    func fetchNewData(completion: @escaping (Result<CurrencyNewModel,Error>) -> ()) {
        guard let url = URL(string: "https://api.fastforex.io/currencies?api_key=7ffe65c2ef-926f01d9e8-r7eql2") else { return }
        URLSession.shared.dataTask(with: url) { data, responce, error in
            if let error = error {
                completion(.failure(error))
                return
            }
            
            guard let safeData = data else { return }
            
            do {
                let currency = try JSONDecoder().decode(CurrencyNewModel.self, from: safeData)
                completion(.success(currency))
            }
            catch {
                completion(.failure(error))
            }
        }
        .resume()
        
    }

}


P.S. If you want to see the API, check the links in fetchData and fetchNewData, It's a free trial, so doesn't matter

CodePudding user response:

Your error says:
Value of type '[Currency]' has no member 'fullName'

So it seems that api.currencies is an array – the array itself has no member fullName, only one single element of it has.

try this:

    ForEach(api.currencies, id:\.self) { currency in
        Text(currency.fullName)
    }
  • Related