0

I am trying to update a field of an object in an array within a class when a dropdown is selected. It seems to be updating on the console but not on display.

This is the class model:

export class HouseInvoice{
    public items:InvoiceItem[] =[];// this is an interface
    
    public static map(obj:{[key:string]:any}):HouseInvoice{
        const houseInvoice = new HouseInvoice();
        houseInvoice.items = obj.items ?? [];
        return houseInvoice;
    }

}

I make the class reactive like this:

let houseInvoice = reactive(new HouseInvoice());

Then i am trying to update the mItem.desc field in one of the items within the main class instance houseInvoice when mItem.name of that same item in the array is changed:

<Table.Tbody>
                  <Table.Tr v-for="(mItem, itemKey) in houseInvoice.items" :key="itemKey">
                    
                    <Table.Td>
                      <div v-if="storedItems.items">
                        <div class="mb-2">
                          <!-- @change="editItemData(itemKey,mItem.id)" -->
                <FormSelect
                  v-model="mItem.name"
                  @change="editItemData(itemKey, mItem.name)"
                  class="w-full"
                >
                <option value="">Select Item</option>
                  <option v-for="sItem in storedItems.items" :key="sItem.id" :value="sItem.id">{{sItem.name}}</option>
                </FormSelect>
              </div>
              <div class="input-form" style="width: 120px;">
<!-- Trying to update this automatically -->
                <FormInput
                v-model="mItem.desc"
                  type="text"
                  placeholder="food and clothes"
                />
              </div>
                      </div>
                      
                    </Table.Td>
...

This is editItemData function:

 const editItemData = (index:number, selectedId:string) =>{
  console.log("index", index);
  console.log("selectedId", selectedId);
  let selectedItem = storedItems.items.find((element)=> element.id == selectedId);
  
  if(selectedItem){

    houseInvoice.items[index].desc = selectedItem.desc ?? "test"; <-- this doesnt update the DOM, but it shows correctly in console.

    // i have tried many things:
    
    // houseInvoice.value.items[index].changeDesc();
    // houseInvoice.items = [mItem];
    
    // methodThatForcesUpdate();
    // console.log("houseInvoice.value:", houseInvoice.value.items);
    // console.log("houseInvoice.items[index]:", houseInvoice.items[index].desc);
    // houseInvoice.value.items.splice(index, 1);
    // houseInvoice.value.items.push(mItem);
    // methodThatForcesUpdate();
    // houseInvoice.value.items.splice(index, 1, mItem);
    // houseInvoice.value.items.push(mItem)
    // setTimeout(() => houseInvoice.value.items.splice(index, 1), 500);
    
  }
  
 }

This is how i add a new item to the array:

const addNewItem = () =>{
  console.log("adding new item");
  let invoiceItem:InvoiceItem = reactive({
    weight: 0,sku: "", id: "",
    name: "", desc: "", height: 0, width: 0,
    length: 0, qty: 1, cubes:0, total: 0
  });
  houseInvoice.items.push(
    invoiceItem
  )
}

I added a picture to help explain. When the drop down list is selected, some text should show up in the bottom text field. What happens is the dom is never updated and nothing shows up in the text field.

enter image description here

Any help would be much appreciated.

crushman
  • 1,023
  • 9
  • 21
  • It's unclear what happens in your case, the reactivity is supposed to work for `items` field. `map` is a mistake because it uses non-reactive HouseInvoice but it's not in use here. `reactive` is not needed in addNewItem but I don't think it would affect the way ot works. Please, provide https://stackoverflow.com/help/mcve for your problem – Estus Flask Mar 12 '23 at 12:47
  • @EstusFlask Adding the new item works just fine. the problem happens when i try to add a value to `mItem.desc` by changing the value of `mItem.name`. Nothing happens to `mItem.desc` It doesnt populate but i can see it gets the new value in the console log – crushman Mar 12 '23 at 13:31
  • Please, provide a way to reproduce. Nothing that is listed looks like a problem to me, at least in Vue 3. `houseInvoice.value.items[index].changeDesc()` suggests that the code differs from what's posted because it's not a ref and there's no changeDesc method – Estus Flask Mar 12 '23 at 13:46
  • @EstusFlask `changeDesc ()` was a function i created while trying to fix the issue but i have long since deleted this. thats why its commented out along with all my other attempts. – crushman Mar 12 '23 at 13:51
  • The question has been wrongly closed as a dupe. Related question but not a dupe, https://stackoverflow.com/questions/67894487/vue-3-reactivity-not-triggered-from-inside-a-class-instance @crushman As noted above, there seems to be no problem in code, the question needs a reproduction of the problem – Estus Flask Mar 13 '23 at 10:58

0 Answers0