2

I currently have a list of recipes that I fetch from a local API upon screen load. This page also has a search field on it that I want to hook up to pull certain data from this API. This API call stores the results in the state of the view. My goal is, when somebody searches, to pull those records and update the state, and reloading the view with new data.

I have seen different ways of doing this with @binding and @state, however, it seems from the examples I've been looking at the binding is in a different struct within another file. In my iteration, however, I just have some functions that pull data from this API. I'd like to avoid using reloadData() as I'd like to use @binding and @state wherever possible in my application.

struct RecipesView: View {
@State var recipes = [Recipe]()
@State var searchText = ""

var body: some View {
    VStack {
        HStack {
            TextField("Search ...", text: $searchText)
                .padding(7)
                .padding(.horizontal, 25)
                .background(Color(.systemGray6))
                .cornerRadius(8)
                .padding(.horizontal, 10)
        }
        VStack{
            HStack {
                Text("Categories")
                    .bold()
                    .multilineTextAlignment(.trailing)
                    .padding(10)
                
                Spacer()
            }
            ScrollView(.horizontal, showsIndicators: false) {
                HStack(spacing: 10) {
                    ForEach(SPIRITS, id:\.self){ spirit in
                        Button("\(spirit)", action: {
                          queryBySpirit(spirit: spirit)
                        })
                        .frame(width: 80, height: 40, alignment: .center)
                        .background(Color("Tope"))
                        .foregroundColor(Color("Onyx"))
                        .cornerRadius(15)
                        .font(.subheadline.bold())
                    }
                }.padding([.leading, .trailing])
            }
        }
        ScrollView {
            VStack {
                ForEach(recipes) { recipe in
                    NavigationLink(destination: RecipeView(recipe: recipe)) {
                        RecipeCard(recipe: recipe)
                    }
                }.padding([.trailing])
            }
        }
    }
    .onAppear(perform: loadData)
    .navigationBarTitle("Recipes")
    .listStyle(InsetGroupedListStyle())

    Color.gray.ignoresSafeArea()
}

func loadData() {
    AF.request("http://localhost:3000/recipes").responseJSON { response in
        guard let data = response.data else { return }
        if let response = try? JSONDecoder().decode([Recipe].self, from: data) {
            DispatchQueue.main.async {
                self.recipes = response
            }
            return
        }
    }
}

func queryBySpirit(spirit: String) {
    AF.request("http://localhost:3000/recipes?spirit=\(spirit)").responseJSON { response in
        guard let data = response.data else { return }
        if let response = try? JSONDecoder().decode([Recipe].self, from: data) {
            DispatchQueue.main.async {
                self.recipes = response
            }
            return
        }
    }
}

}

How can I use @binding within this file to take advantage of the hot reloading? Or, based on my iteration will I need to leverage reloadData() instead?

Spefically, I'd like to avoid using reloadData() as seen here: Swift CollectionView reload data after API call

I'd love to be able to leverage Changing @State variable does not update the View in SwiftUI

However I'm unsure of how to do that with what I have currently.

  • It is not clear what you are asking here. You talk about using `reloadData()`, but you don't have such function. You want to use @binding and @state and you already have `@State var recipes`. "...How can I use @binding within this file to take advantage of the hot reloading?" where do you do, or want to do, the "hot" reloading? Why do you want to use binding, you already have `@State var recipes` – workingdog support Ukraine Sep 08 '21 at 04:46
  • 1
    Having a `state` (`@State`) variable update should reload the view.. Thats how SwiftUI works. Both the functions (`loadData ``queryBySpirit `) should update the view. Maybe the the request is retuning an error or the codeable object has the wrong keys. – Alhomaidhi Sep 08 '21 at 09:04

0 Answers0