Hello,
I am following the Swift course and am stuck with the Grids chapter on the Cookademy project.
I had errors in prior chapters I could research myself, as Xcode and Swift changed since the course material was introduced, but with this example I am stuck.
In the extension of the RecipesListView I am getting the error message
Cannot call value of non-function type ‘[Recipe]’
for this code piece
private var recipes: [Recipe] {
recipeData.recipes(for: category)
}
The whole extension goes as follows
extension RecipesListView {
func recipes(for category: MainInformation.Category) -> [Recipe] {
var filteredRecipes = [Recipe]()
for recipe in recipeData.recipes {
if recipe.mainInformation.category == category {
filteredRecipes.append(recipe)
}
}
}
private var recipes: [Recipe] {
recipeData.recipes(for: category)
}
private var navigationTitle: String {
"\(category.rawValue) Recipes"
}
}
Any help would be appreciated.
Kind regards
1 Like
I’m getting the same issue. Were you able to solve it?
I had the same issue. After comparing every line so far and trying to find a typo I gave up and downloaded the sample project.
There I saw, that the function seems to be incomplete in the article: There is no return statement at the end.
excerpt from the sample project code:
func recipes(for category: MainInformation.Category) -> [Recipe] {
var filteredRecipes = [Recipe]()
for recipe in recipes {
if recipe.mainInformation.category == category {
filteredRecipes.append(recipe)
}
}
return filteredRecipes
}
Edit: However, now I have the issue that the categories don’t get properly filtered. I just have all the recipes no matter what category I select.
After some further investigation i found the reason for my non filtered lists:
the func recipes never gets called. Studying the sample project I discovered that the ForEach condition within the body of RecipesListView had been updated:
var body: some View {
List {
//recipes in ForEach(recipes) refers to the func recipes; returns filteredRecipes
ForEach(recipes) { recipe in
NavigationLink(recipe.mainInformation.name, destination: RecipeDetailView(recipe: recipe))
}
.listRowBackground(listBackgroundColor)
.foregroundColor(listTextColor)
}
.navigationTitle(navigationTitle)
Might have been an oversight by me, but I didn’t notice the change in the articles of Cookcademy thus far.
The func recipes needs to be in the RecipeData ViewModel
class RecipeData: ObservableObject {
@Published var recipes = Recipe.testRecipes
func recipes(for category: MainInformation.Category) -> [Recipe] {
var filteredRecipes = [Recipe]()
for recipe in recipes {
if recipe.mainInformation.category == category {
filteredRecipes.append(recipe)
}
}
return filteredRecipes
}
}
You will need to change the CookcademyApp to start at RecipeCategoryGridView()
@main
struct CookcademyApp: App {
var body: some Scene {
WindowGroup {
RecipeCategoryGridView()
}
}
}
Here’s what’s missing/wrong with the code as you follow along. When following along, you’ll hit a snag and see the error Cannot call value of non-function type ‘[Recipe]
.
Basically, recipeData is not a function, but a private var (private var recipeData: RecipeData
), which is why XCode complains you’re calling a non-function. Once you call the actual function (func recipes(for category: MainInformation.Category) -> [Recipe]
), the code works as expected.
Change:
private var recipes: [Recipe] {
recipeData.recipes(for: category)
}
To:
private var recipes: [Recipe] {
recipes(for: category)
}
This will fix it, but then you’ll run into the error Missing return in instance method expected to return '[Recipe]' error
, so you need to add return
, which is not in any of the code samples:
extension RecipesListView {
func recipes(for category: MainInformation.Category) -> [Recipe] {
var filteredRecipes = [Recipe]()
for recipe in recipeData.recipes {
if recipe.mainInformation.category == category {
filteredRecipes.append(recipe)
}
}
return filteredRecipes
}
Once that’s done, you can continue the exercise as normal.