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"
}
}
}
}
}
}
