Home > database >  Variable not being assigned in didSelectRowAt after model returns data
Variable not being assigned in didSelectRowAt after model returns data

Time:03-04

I have the following Model that returns data to my View Controller:

    func getRecipeSelected(docId: String, completionHandler: @escaping () -> Void) {
        db.collection("recipes").document(docId).getDocument { document, error in
            if let error = error as NSError? {
            }
            else {
                if let document = document {
                    do {
                        self.recipe = try document.data(as: Recipe.self)
                        
                        let recipeFromFirestore = Recipe(
                            id: docId,
                            title: self.recipe!.title ?? "",
                            analyzedInstructions: self.recipe!.analyzedInstructions!)
                        
                        DispatchQueue.main.async {
self.delegateSpecificRecipe?.recipeSpecificRetrieved(recipeSelected: recipeFromFirestore)
                        }
                    }
                    catch {
                        print("Error: \(error)")
                    }
                }
            }
        }
        completionHandler()
    }

And this is in my View Controller:

    var entireRecipe: Recipe? = nil

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        documentID = recipeDocIdArray[indexPath.row]
        
        model.getRecipeSelected(docId: documentID) {
            print("ISSUE HERE: \(self.entireRecipe)") // FIXME: THIS IS NIL THE FIRST TIME IT IS CALLED
        }
    }

My issue is that entireRecipe isn't assigned the data from the model within the completion handler in my View Controller. If I were to tap the cell for the second time, then the data from the first tap is assigned in that completion handler.

How can I assign the returned data to the entireRecipe within that scope the first time it is tapped?

CodePudding user response:

You are calling delegate method instead of calling completionHandler. And you are also calling delegate method in async block which one called after completionHandler. Don’t need two of them in a row. You can use completionHandler like:

func getRecipeSelected(docId: String, completionHandler: @escaping (Recipe?) -> Void) {
        db.collection("recipes").document(docId).getDocument { document, error in
            if let error = error as NSError? {
            }
            else {
                if let document = document {
                    do {
                        self.recipe = try document.data(as: Recipe.self)
                        
                        let recipeFromFirestore = Recipe(
                            id: docId,
                            title: self.recipe!.title ?? "",
                            analyzedInstructions: self.recipe!.analyzedInstructions!)
                        
                        completionHandler(recipeFromFirestore)
                    }
                    catch {
                        print("Error: \(error)")
                        completionHandler(nil)
                    }
                }
            }
        }
    }
var entireRecipe: Recipe?

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
    documentID = recipeDocIdArray[indexPath.row]
        
    model.getRecipeSelected(docId: documentID) { [weak self] model in
        self?.entireRecipe = model
    }
}
  • Related