Home > Software engineering >  Firestore responding with "cannot find 'cards' in scope"
Firestore responding with "cannot find 'cards' in scope"

Time:10-23

I followed this tutorial to get data from firestore and changed what i needed to correspond to my model but it keeps responding with "cannot find 'cards' in scope" and I'm not sure what i did wrong. (i think i got the mvvm labels right)

VIEW

import SwiftUI

struct TestingView: View {

@ObservedObject private var viewModel = CardViewModel()

var body: some View {
    List(viewModel.cards) {
        Text(cards.name)
    }
    .onAppear() {
        self.viewModel.fetchData()
    }
  }
} 

VIEW MODEL

import Foundation
import Firebase

class CardViewModel: ObservableObject {
@Published var cards = [Cards]()

private var db = Firestore.firestore()

func fetchData() {
 db.collection("cards").addSnapshotListener { (querySnapshot, error) in
  guard let documents = querySnapshot?.documents else {
    print("No documents")
    return
  }
  self.cards = documents.map { queryDocumentSnapshot -> Cards in
    let data = queryDocumentSnapshot.data()
      let name = data["name"] as? String ?? ""
      let pronoun = data["pronoun"] as? String ?? ""
      let bio = data["bio"] as? String ?? ""
      let profileURLString = data["profileURLString"] as? String ?? ""
      let gradiantColor1 = data["gradiantColor1"] as? UInt ?? 0
      let gradiantColor2 = data["gradiantColor2"] as? UInt ?? 0
      let gradiantColor3 = data["gradiantColor3"] as? UInt ?? 0
      
    return Cards(name: name, pronoun: pronoun, bio: bio, profileURLString:   profileURLString, gradiantColor1: gradiantColor1, gradiantColor2: gradiantColor2, gradiantColor3: gradiantColor3)
      }
    }
  }
}

MODEL

import Foundation

struct Cards: Identifiable {
    var id = UUID().uuidString
    var name: String
    var pronoun: String
    var bio: String
    var profileURLString: String

    var gradiantColor1: UInt
    var gradiantColor2: UInt
    var gradiantColor3: UInt

    var profileURL: URL {
        return URL(string: profileURLString)!
    }
 }

CodePudding user response:

List will provide an element to its trailing closure -- see card in in my code. Then, you can access that specific card in your Text element.

var body: some View {
    List(viewModel.cards) { card in //<-- Here
        Text(card.name) //<-- Here
    }
    .onAppear() {
        self.viewModel.fetchData()
    }
  }
} 

I'd suggest that you might want to rename the struct Cards to struct Card since it is one card. Then, your array would be @Published var cards = [Card]() -- ie an array of Cards. From a naming perspective, this would make a lot more sense.

  • Related