Home > Back-end >  How do I pass data from a variable in a view to a view model class
How do I pass data from a variable in a view to a view model class

Time:09-19

I have data contained in a variable called selectedFolderId, and the intent of this is I want to pass this data in this variable into a class whereby I read contents of my database from firestore anytime the ShoppingListItemsView loads.

I would appreciate help from anyone if they can explain and show me how to pass this data from my ShoppingListItemsView into my ListRepository class where i will further use this data to do a query.

Here are the ShoppingListItemsView and the ListRepository classes:

import SwiftUI
import November

struct ShoppingListItemsView: View {
    
    @ObservedObject var taskListVM = ShoppingListItemsViewModel()
    @EnvironmentObject var sessionService: SessionServiceImpl
    @EnvironmentObject var searchBarModel: SearchBarModel
    @ObservedObject var folderListVM = FolderListViewModel()
    @ObservedObject var listRepository = ListRepository()
    
    let tasks = testDataTasks
    
    var selectedFolderTitle = ""
    var selectedFolderDate = ""
    var selectedFolderId = ""
    
    @State var presentANewItem = false
    
    var body: some View {
            VStack {
                List{
                    ForEach(taskListVM.taskCellViewModels){ taskCellVM in
                        TaskCell(taskCellVM: taskCellVM)
                    }
                    if(presentANewItem == true){
                        TaskCell(taskCellVM: ShoppingListItemCellViewModel(task: ListItem(listTitle: "", completed: false, selectedFolderId: selectedFolderId))) { task in
                            self.taskListVM.addTask(task: task)
                            self.presentANewItem.toggle()
                        }
                    }
                }
//                .onAppear {
//                    // Set the default to clear
//                    UITableView.appearance().backgroundColor = .clear
//                }
                Button (action: { self.presentANewItem.toggle() }, label : {
                    HStack{
                        Image(systemName: "plus.circle.fill")
                            .resizable()
                            .frame(width: 20, height: 20)
                            .foregroundColor(.white)
                        Text("Add New Item")
                            .foregroundColor(.white)
                            .font(.system(size: 15.0))
                            .fontWeight(.bold)
                    }
                    .padding(3)
                    .background(Color.cartvoltDarkBlue)
                    .cornerRadius(10)
                    .shadow(color: Color.cartvoltDarkBlue.opacity(0.9), radius: 5, x: 5, y: 5)
                })
                .padding(.bottom)

            }
            .onAppear{
                
            }
            .navigationTitle("\(selectedFolderTitle) • \(selectedFolderDate)")
            .navigationBarTitleDisplayMode(.inline)
    }
}
import Foundation
import Firebase
import FirebaseFirestore
import FirebaseFirestoreSwift

class ListRepository: ObservableObject {
    let db = Firestore.firestore()
    
    @Published var tasks = [ListItem]()
    @Published var selectedFolderId = ""
    
    init(){
        loadData()
    }
    
    func loadData() {
        let userId = Auth.auth().currentUser?.uid
        
        db.collection("listItems")
            .order(by: "createdTime")
            .whereField("userId", isEqualTo: userId)
            .addSnapshotListener { (querySnapshot, error) in
            if let querySnapshot = querySnapshot {
                self.tasks = querySnapshot.documents.compactMap { document in
                    do {
                        let x = try document.data(as: ListItem.self)
                        return x
                    }
                    catch {
                        print(error)
                    }
                    return nil
                }
            }
        }
    }
}

Preferably I would like to move the data contained in the selectedFolderId variable in ShoppingListItemsView when it loads, as you can see the onAppear{}, into the selectedFolderId variable in ListRepository class where I will later use it in a query.

Would mean a lot if someone can work this out for me

CodePudding user response:

Hi Emere and welcome to SO. To get fast and quality answers please read this article Minimal reproducible example

Any way your case doesn't seems difficile and you can achieve your goal by creating a func in ListRepository that will accept an argument from ShoppingListItemsView and rewrite selectedFolderId. Call that func from your view anytime when you want to set new selectedFolderId.

Add this func to ListRepository:

func setSelectedFolderId(id: String) {
    self.selectedFolderId = id
}

Add this modification to View that should change selectedFolderIs when you tap on item and pass new value into the function.

.onTapGesture { listRepository.setSelectedFolderId(id: String) }

CodePudding user response:

Add this function to ListRepository

func selectedFolderId(id: String) {
    self.selectedFolderId = id
}

and replace in ShoppingListItemsView

ForEach(taskListVM.taskCellViewModels){ taskCellVM in
  TaskCell(taskCellVM: taskCellVM)
}

by

ForEach(taskListVM.taskCellViewModels){ taskCellVM in
  TaskCell(taskCellVM: taskCellVM)
    .onTapGesture { listRepository.selectedFolderId(id: taskCellVM.id) }
}

I assumed it is taskCellVM.id which gives the id

With each tap on the cell, the id will change

  • Related