Utilizing data as a substitute when creating a SearchBar using Vue3

My VueJs3 application has a search bar implemented using .filter(), and it seems to be working fine. However, when I try to pass the value from my methods to the template, an error occurs. My data becomes a proxy and I am unable to use it in that format.

Here is the code snippet:

<template>
  <div class="searchBar">
    <input type="search" v-on:change="filterList" />
    {{ search }}
  </div>
  <div id="listaDestaque" class="list">
    <div class="list-header">
      <p>Imagem</p>
      <p>Descrição</p>
      <p>Categoria</p>
      <p>Un</p>
      <p>Estoque</p>
      <p>Valor</p>
    </div>
    <div v-for="item in current_data">
      <div class="item-list">
        <img v-bind:src="item.attributes.image" class="item-image" />
        <p>{{ item.attributes.name }}</p>
        <p>{{ item.attributes['category-name'].name }}</p>
        <p>{{ item.attributes['unit-name'].name }}</p>
        <p>{{ item.attributes['quantity-in-stock'] }}</p>
        <p>{{ item.attributes.price }}</p>
      </div>
    </div>
  </div>
</template>

<script lang="ts">
import { defineComponent } from 'vue';
import api from '../../services/axios.js';
import headers from '../../services/headers.js';

export default defineComponent({
  name: 'listaDestaque',
  data() {
    return { myList: [], search: '', filter: '', current_data: '' };
  },
  beforeMount() {
    api.get('/products/all', headers).then((response) => {
      this.myList = response.data.data;
      const filter = this.myList.filter((element) => element.attributes.highlight == true);
      this.current_data = filter;
    });
  },
  methods: {
    filterList() {
      this.$data.search = event.target.value;
      console.log(this.search);

      const myListArray = JSON.parse(JSON.stringify(this.myList));

      const filtered = myListArray.find(
        (element) => element.attributes.name == this.search
      );

      const filteredArray = JSON.parse(JSON.stringify(filtered));

      if (filtered) {
        this.current_data = filteredArray;
        console.log(this.current_data);
        console.log(filteredArray);
      }
    },
  },
});
</script>

<style scoped></style>

The section related to the search bar is between lines 2-5 and 35-65.

The output of console.log(filteredArray); on line 64 looks like this:

Proxy {id: '1', type: 'products', attributes: {…}, relationships: {…}}
[[Handler]]: Object
[[Target]]: Object
attributes: {name: 'Small Marble Chair', description: 'Nihil est dignissimos. Quia officia velit. Est aliquid eos.', quantity-in-stock: 12, price: 58.21, highlight: true, …}
id: "1"
relationships: {category: {…}, unit: {…}}
type: "products"
[[Prototype]]: Object
[[IsRevoked]]: false

An error occurs on lines 17-22 after utilizing the function filterList:

listaDestaque.vue:17 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'image')
    at listaDestaque.vue:17:42
    at renderList (runtime-core.esm-bundler.js:2905:26)
    at Proxy._sfc_render (listaDestaque.vue:24:11)
    at renderComponentRoot (runtime-core.esm-bundler.js:896:44)
    at ReactiveEffect.componentUpdateFn [as fn] (runtime-core.esm-bundler.js:5651:34)
    at ReactiveEffect.run (reactivity.esm-bundler.js:185:25)
    at instance.update (runtime-core.esm-bundler.js:5694:56)
    at callWithErrorHandling (runtime-core.esm-bundler.js:155:36)
    at flushJobs (runtime-core.esm-bundler.js:396:17)

Answer №1

Changing a value to a proxy should not pose any problems.

The issue lies in the usage of

const filtered = myListArray.find(...)
. The result of the find method is either null or the first object in the array that matches your criteria. Hence, filteredArray will never contain an array. When this is passed to the template with a for in loop, the iterator will cycle through the properties of each object. For instance, at some point, item may become attributes, causing attributes.attributes to be undefined, resulting in an error when accessing attributes.attributes.image.

It seems you intended to use filter instead of find.

  const filtered = myListArray.filter(
    (element) => element.attributes.name == this.search
  );

This solution appears to be overly complex.

You can simplify it by using v-model for the search input and creating a computed dataset.

For example: (SFC)

<template>
  <div class="searchBar">
    <input type="search" v-model="search"/>
    {{ search }}
  </div>
  <table id="listaDestaque" class="list">
    <thead>
      <tr>
        <th>Description</th>
        <th>Category</th>
        <th>Stock</th>
        <th>Price</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="item in current_data">
        <td>{{ item.attributes.name }}</td>
        <td>{{ item.attributes['category-name'] }}</td>
        <td>{{ item.attributes['quantity-in-stock'] }}</td>
        <td>{{ item.attributes.price }}</td>
      </tr>
    </tbody>
  </table>
</template>

<script lang="ts">
  import { defineComponent } from 'vue';
  
  const dataset = [
    {attributes:{name:"apple", "category-name":"fruit", "quantity-in-stock": 0.2, price: "$3.98"}},
    {attributes:{name:"pear", "category-name":"fruit", "quantity-in-stock": 2, price: "$1.98"}},
    {attributes:{name:"orange", "category-name":"fruit", "quantity-in-stock": 3, price: "$3.98"}},
    {attributes:{name:"iPhone", "category-name":"not fruit", "quantity-in-stock": 18, price: "$398.29"}},
  ]

  export default defineComponent({
    name: 'listaDestaque',
    data() {
      return { myList: [], search: ''};
    },
    beforeMount() {
      // simulated API call
      setTimeout(()=>{
        this.myList = dataset  
      }, 500);
    },
    computed: {
      current_data(){
        return this.myList.filter((element) => element.attributes.name.includes(this.search)) || [];
      }
    },
  });
</script>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Transferring account information to a function call in the near-js-api

I am attempting to utilize the following method in near-js-api for my contract. It requires a Rust AccountId as input. What is the correct procedure to serialize an Account and send it to the contract? Also, are there any specific considerations when inv ...

Pass along computed style data to the parent component in Vue.js

I am relatively new to VueJS and currently in the process of exploring its features. One specific issue I am facing on my website involves a TopBar component that includes both the logo and the menu. <template> <div id="topBar"> <div ...

How can I extract data from the 'ngx-quill' editor when integrating it with a FormBuilder in Angular?

After implementing the 'ngx-quill' editor package in my Angular 15 project, I encountered an issue where the value of the content form control was returning 'null' upon form submission using FormBuilder. Despite entering text such as he ...

I have developed a website that can calculate the factorial of any given number. The next step is to design a function that will display the step-by-step mathematical process

Could use a hand with this one. The function below is empty and I'm a bit stuck on what to do next. Right now, the webpage displays the factorized number, but I want to show the mathematical equation before it, like so: User inputs: 3 Site outputs: " ...

Can you retrieve a reference/pointer to a specific property of an object in JavaScript?

I am looking to generate an HTML <input> element, and then access its value property so I can update the value through that reference: var input = document.createElement('input'); var valueRef = &(input.value); *valueRef = "Hello world!" ...

Implementing a blur effect on a CSS loader

I have successfully implemented a loader feature where a loading animation is displayed upon clicking the submit button, indicating that the form submission is in progress. However, I am encountering an issue when trying to apply a blur effect to the entir ...

React Native, state values are stagnant

I created an edit screen where I am attempting to update the post value through navigation v4 using getParams and setParams. However, when I modify the old value and click the save button, it does not update and no error is displayed. The old values still ...

Menu icon in Next.js/React/Tailwind not triggering close action when clicked again, causing responsiveness issue

Hey there, I'm relatively new to working with Next.js and React. Right now, I'm tackling the challenge of creating a responsive navbar that toggles open and closed when clicking on the hamburger icon (and should also close when clicked outside th ...

A simple method to obtain the ID of the element that has been clicked and save it in a variable to be utilized in a function responsible for

Seeking assistance in optimizing the code below by removing the specific #static id and allowing for dynamic IDs such as #dynamic within the one click function. This would eliminate the need to repeatedly copy and paste the same function with different ID ...

how to adjust the width of table columns dynamically using ng-repeat and AngularJS

Working on a user interface that contains a table where the column widths adjust according to percentage data. I'm using ng-repeat to populate the table, but need help setting unique widths for each piece of data received. Here's some of my Angul ...

Having an issue with retrieving value from a textfield in JavaScript

<input id="checkOldPassword" type="button" title="Check New Password" value="Check New Password" onclick="checkPassword()" /> <input id="newPassword" type="text" maxlength="8" min="8" /> <script language="javascript"> function checkPassw ...

An easy way to attach a Contextmenu to a specific element

I have implemented a scrolling feature for one of the div elements in my Application. Inside this div, there is a templated table with over 100 rows. Users are able to add or delete rows using a contextMenu. The contextMenu offers 4 options - AddTop, AddB ...

The crossIcon on the MUI alert form won't let me close it

I am facing an issue with my snackBar and alert components from MUI. I am trying to close the alert using a function or by clicking on the crossIcon, but it's not working as expected. I have used code examples from MUI, but still can't figure out ...

The process of incorporating the dymo.framework into an Angular project

My Angular project is currently in need of importing dymo.connect.framework. However, I am facing some challenges as the SDK support provided by dymo only explains this process for JavaScript. I have also referred to an explanation found here. Unfortunate ...

Strange problem encountered while using npm

Hello, I am encountering an issue where I run the command: npm run watch and it provides the following output: /public/js/app.js 1.94 MiB /public/js/app [emitted] /public/js/app // large list of files and sizes /// public/css/app.css 193 ...

Add characters to div using JavaScript

I am curious about which framework, if any, would be most effective for capturing keystrokes and adding them to an HTML element such as a "p" element. My goal is to allow the client to type something on the keyboard and have it immediately displayed in the ...

ReactJS Error: Attempting to access undefined property "updateNumber"

Just getting my feet wet with js and React, attempting to create a simple Sudoku program. Encountering an issue when adding UpdateNumberInCell={this.updateNumber} as a property in the Cell component - receiving the error: "Uncaught TypeError: Cannot read ...

Image Carousel Extravaganza

Trying to set up a sequence of autoplaying images has been a bit of a challenge for me. I've attempted various methods but haven't quite nailed it yet. Take a look at what I'm aiming for: https://i.stack.imgur.com/JlqWk.gif This is the cod ...

make the chosen text appear on Internet Explorer

1 How to insert text into a text box using code? 2 Moving the caret to the end of the text. 3 Ensuring the caret is visible by scrolling the text box content. 4 Programmatically selecting specific text in a textbox. 5 **How to make selected text visible?** ...

No information is being emitted by the subject

In my application, I have a feature where users input data that needs to be validated in a form. Once the validation is successful, a button is enabled allowing the user to submit their order. However, I'm facing an issue with this specific component ...