0

Used this scenario as an example to be a bit more self explanatory. I have a struct which represents a character, and one of the structs attributes is another struct: Stats (where I used id to represent the name in a more simple way).

Besides that I have a view with a ForEach, where I iterate over some Characters and I need to be able to increase a specific stat.

The problem is: I'm trying to increase stat.points using a button, but I keep getting the message "Left side of mutating operator isn't mutable: 'product' is a 'let' constant".

struct Character: Identifiable {
   var id: String
   var name: String
   var stats: [Stats]
}

struct Stats: Identifiable {
   var id: String
   var points: Int
}


ForEach(characters.stats) { stat in
   HStack {
      Text("\(stat.id)")
      Button {
         stat.points += 1
      } label: {
         Text("Increase")
      }
   }
}

How could I make this work?

1
  • Welcome to SO - Please take the tour and read How to Ask to improve, edit and format your questions. Without a Minimal Reproducible Example it is impossible to help you troubleshoot. Commented Oct 29, 2022 at 23:19

1 Answer 1

1

As you have found, structs in your stats: [Stats] does not allow changes especially in a ForEach where it is a let.

There are many ways to achieve what you want, depending on what you trying to do.

This example code shows the most basic way, using the array of stats: [Stats] directly:

struct ContentView: View {
    @State var characters = Character(id: "1",name: "name-1", stats: [Stats(id: "1", points: 1),Stats(id: "2", points: 1)])
    
    var body: some View {
        ForEach(characters.stats.indices, id: \.self) { index in
            HStack {
                Text("\(characters.stats[index].id)")
                Button {
                    characters.stats[index].points += 1
                } label: {
                    Text("Increase")
                }
                Text("\(characters.stats[index].points)")
            }
        }
    }
}

Here is another approach, using a function, to increase your stat points value:

struct ContentView: View {
    @State var characters = Character(id: "1", name: "name-1", stats: [Stats(id: "1", points: 1), Stats(id: "2", points: 1)])
    
    var body: some View {
        ForEach(characters.stats) { stat in
            HStack {
                Text("\(stat.id)")
                Button {
                    increase(stat: stat)
                } label: {
                    Text("Increase")
                }
                Text("\(stat.points)")
            }
        }
    }
    
    func increase(stat: Stats) {
        if let index = characters.stats.firstIndex(where: {$0.id == stat.id}) {
            characters.stats[index].points += 1
        }
    }
    
}
Sign up to request clarification or add additional context in comments.

Comments

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.