Home > OS >  How can I create a function to search for an ID, locate and change one field of this record?
How can I create a function to search for an ID, locate and change one field of this record?

Time:03-06

Model:

enum TaskType: Int, Codable {
    
    case upcoming = 0
    case inProgress
    case testing
    case completed
    
    var title: String {
        switch self {
        case .upcoming:
            return "Upcoming"
        case .inProgress:
            return "In Progress"
        case .testing:
            return "Testing"
        case .completed:
            return "Completed"
        }
    }
}

struct TasksModel: Encodable, Decodable {
    
    var upcomingArray: [TaskInfo]
    var inProgressArray: [TaskInfo]
    var testingArray: [TaskInfo]
    var completedArray: [TaskInfo]
}

struct TaskInfo: Codable, Equatable, Identifiable {
    
    var id: String
    var title: String
    var description: String
    var taskStatus: TaskType
    var taskDate = Date()
}

VM:

class HomeVM: ObservableObject {
            
      @Published var tasksArray: TasksModel
                    
      self.tasksArray = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])
}

So I want a function like below where it receives the id (taskID) for the search and I want to locate the record with that id and I can change the value of the taskStatus from what it is to another (i.e.: from upcoming to testing).

func inProgressSetTask(taskID: String) {
    
    @StateObject var viewModel = HomeVM()
    
    if let index = viewModel.tasksArray.inProgressArray.first(where: taskID) {
        // Complete code to change taskStatus
    }
    print("InProgress Set ID# \(taskID)")
}

But this way I’m trying, it displays an error saying that can’t convert from String to expected ‘(TaskInfo). I would be trying this code if let index to each array in TasksArray (inProgressArray, CompletedArray, etc), is there any way to look into all arrays at once ?

Appreciate any help.

CodePudding user response:

You are attempting to compare a String to a TaskInfo, because the elements of an inProgressArray are of type TaskInfo. What you need to do is drill into the array and get to the .id. That is simple to do. In the .first(where:), you simply pass a closure of $0.id == taskID.

    if let index = viewModel.tasksArray.inProgressArray.first(where: { $0.id == taskID } ) {

CodePudding user response:

you could try the following example code to achieve what you want:
(note, you should have @StateObject var viewModel = HomeVM() outside of the func inProgressSetTask(taskID: String) {...} or pass it in as a parameter)

EDIT-1:

func inProgressSetTask(taskID: String) {
    print("InProgress Set ID# \(taskID)")
    
    // with index, using `firstIndex`
    if let index = viewModel.tasksArray.inProgressArray.firstIndex(where: {$0.id == taskID}) {
        // do something with the index
        viewModel.tasksArray.inProgressArray[index].title = "xxx"
    }
    
    // with TaskInfo, using `first`
    if var taskInfo = viewModel.tasksArray.inProgressArray.first(where: {$0.id == taskID}) {
        // do something with the taskInfo
        taskInfo.title = "xxx"
    }
    
    // with all arrays of TaskInfo, use the `func setTaskFromAll(...)` in `HomeVM`
}

class HomeVM: ObservableObject {
    @Published var tasksArray: TasksModel = TasksModel.init(upcomingArray: [], inProgressArray: [], testingArray: [], completedArray: [])

    func setTaskFromAll(taskID: String) {
        if let index = tasksArray.inProgressArray.firstIndex(where: {$0.id == taskID}) {
            tasksArray.inProgressArray[index].title = "inProgress"
        } else {
            if let index = tasksArray.completedArray.firstIndex(where: {$0.id == taskID}) {
                tasksArray.completedArray[index].title = "completed"
            } else {
                if let index = tasksArray.testingArray.firstIndex(where: {$0.id == taskID}) {
                    tasksArray.testingArray[index].title = "testing"
                } else {
                    if let index = tasksArray.upcomingArray.firstIndex(where: {$0.id == taskID}) {
                        tasksArray.upcomingArray[index].title = "upcoming"
                    }
                }
            }
        }
    }
    
}
  • Related