1
struct NotesView: View {
    @State var notesArray = [Note]()
    public var deleteid: String
    var body: some View {

List{
      ForEach(notesArray, id: \._id) { notesArray in
                        NavigationLink(destination: AddNotesView(addNotesViewIdentifier: "updateNote", id: notesArray._id, title: notesArray.title, note: notesArray.note, noteDate: notesArray.date)){
    HStack {
       Text(notesArray.title)
       deleteid = notesArray._id //ERROR - Cannot assign to property: 'self' is immutable
       
                 }
             }
        }
   .onDelete(perform: deleteNoteAtIndex)
  }
}
func deleteNoteAtIndex(at offsets: IndexSet){ APIFunctions.functions.DeleteNote(id: _id) }

I was expecting the variable "deleteid" to update.

I assumed you can modify any variable by calling that variable and set it equal to a new value.

Like this

First declare variable:

var deleteid: String

next modify variables string valve

deleteid = notesArray._id

1 Answer 1

1

A couple of things:

  1. This isn't directly related to your question, but may help you navigation your own code better... When you create a ForEach view to iterate over an array, you should use a different name for the value that represents each element in the iteration. Here, you're using the name notesArray for your array of notes, then creating a second local variable called notesArray for the loop. That variable inside the block will be an instance of Note, so I'd name it note, e.g.:

    ForEach(notesArray, id: \._id) { note in
       NavigationLink(destination: AddNotesView(addNotesViewIdentifier: note._id, // etc
    }
    
  2. If you want variables to be modifiable inside views, they should be @State variables. This is important due to the way Swift struct lifecycles work, and how the SwiftUI rendering system loads and reloads structs as it works out what has changed.

  3. I'm not entirely sure what deleteid is supposed to represent here, and it's possible you don't need it at all. If you're using the onDelete modifier to implement SwiftUI's native swipe-to-delete system, SwiftUI will give you an IndexSet, which is a collection (usually of just one) of the positions of the item(s) to delete in the array.

    From there, you can find the item(s) at each index and then either remove them, or lookup some other value (e.g., their _id attribute) and do some other operation on them.

    So the method you might call in onDelete could look something like:

     func deleteNoteAtIndex(offsets: IndexSet) {
       // get the array objects that the offsets point to
       let notes = offsets.map { noteArray[$0] }
    
       for note in notes {
         APIFunctions.functions.deleteNote(id: note._id)
       }
     }
    
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you, and you are exactly right regarding deleteid. I was trying to pass the variable notesArrays._id from the loop to .onDelete(perform: deleteNoteAtIndex) function that I created but cannot figure out how to get the _id valve to the function. I have a "route" in a separate swift file "APIFunctions.swift" called "DeleteNote" that will delete the note from mongodb
This is my function. 'func deleteNoteAtIndex(at offsets: IndexSet){ APIFunctions.functions.DeleteNote(id: _id) }'
@JamesJCreston OK, I've added an example of what your onDelete function could look like that works solely from the offsets SwiftUI provides you. This way you don't need to set a deleteId yourself.
Scott, thank you. That is exactly what I was attempting to accomplish. It works and has helped me learn a little more about SwiftUI. I appreciate your help and your time!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.