Accessing a component's function from an HTML view in a Vue application

I seem to be stuck in a tricky situation with Vue logic. I have a "list" component that retrieves results from an ajax call. The issue arises when I try to incorporate a search field. Here is what I currently have:

search.vue

<template>
  <div>
    <div v-for="(result, index) in results">
      <h2>{{ result.name }}</h2>
    </div>
  </div>
</template>

<script>
  export default {
    name : 'searchList',

    data() {
      return { results: [] }
    }

    created: function(){
      this.goSearch();
    },

    methods : {
      goSearch : function(){
        this.results = axios.get('/search');
      }
    }
  }
</script>

This setup works perfectly, but now I want to add a search input field. I've researched and discovered that I need to use another component for this, but I don't want to create a separate component just for an input field. My idea is to do something like this:

index.html

<input type="text" v-model="goSearch">

<search-list></search-list>

However, the problem I'm encountering is that Vue is throwing an error:

[Vue warn]: Property or method "goSearch" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.

I've also attempted using v-bind="goSearch", but that didn't work either. Any suggestions on how to make this work?

UPDATE: I've added a button to trigger the function:

<button @click="goSearch"></button>

The "goSearch" function now attempts to retrieve the value from the text box, but even this approach is not functioning. Any insights on how to achieve this successfully?

Answer №1

The reason you're encountering this error is because of the following code you're using:

<input type="text" v-model="goSearch">

In this case, "goSearch" is considered as data by Vue, but Vue cannot find this data because you actually intended it to be a method. This is not how Vue operates. If you want to bind a method, you should not use v-model. Instead, you should use v-on:input

<input type="text" v-on:input="goSearch">

Answer №2

The issue arises from the fact that the goSearch method is confined within the searchList component, making it inaccessible to elements outside of it, such as the input element, hence the warning message.

One possible resolution is to define the method in the parent component (likely index.html in this case), allowing all child components to utilize it.

Furthermore, it is necessary to store the results array within the parent component's data and transmit it to the searchList component using props along with the goSearch function, as shown below:

search.vue

<template>
    <div>
        <div v-for="(result, index) in results" v-bind:key="index"gt;
            <h2>{{ result.title }}</h2>
        </div>
    </div>
</template>

<script>
  export default {
    name: 'searchList',
    props: ['results'],
    created: function () {
      this.$emit('goSearch')
    }
  }
</script>

Parent component:

<template>
  <div id="app">
    <button v-on:click="goSearch">Get Random Post</button>
    <search-list
            v-on:goSearch="goSearch"
            v-bind:results="results"
    ></search-list>
  </div>
</template>

<script>
import searchList from './components/searchList'

export default {
  name: 'App',
  data () {
    return { results: [] }
  },
  components: {
    searchList
  },
  methods: {
    goSearch: function () {
      const postId = Math.floor(Math.random() * (100 - 1 + 1)) + 1
      fetch('https://jsonplaceholder.typicode.com/posts/' + postId)
        .then(response => response.json())
        .then(json => {
          this.results = [json]
        })
    }
  }
}
</script>

It is important to note that when multiple components require the same property/method, it should be declared in a parent component and then passed to the child components using props, allowing the children to trigger parent events using emit.

https://i.sstatic.net/esL6k.png

For additional insights, you may refer to this answer.

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

Execution of Ajax call fails to occur synchronously

I have created a unique weather website that utilizes the flickr API as well as the yahoo API to gather weather data. However, I am facing an issue where the ajax call from the yahoo API does not retrieve the necessary data in time for the content of the p ...

Exploring protractor and webdriver basics in the context of a non-angular application

Currently, I am in the process of writing end-to-end tests for a non-angular application using Protractor. While there is a wealth of information available on how to achieve this, it appears that there are multiple approaches to consider. This has led me ...

Tips for implementing JWT in a Node.js-based proxy server:

I am a Node.js beginner with a newbie question. I'm not sure if this is the right place to ask, but I need ideas from this community. Here's what I'm trying to do: Server Configurations: Node.js - 4.0.0 Hapi.js - 10.0.0 Redis Scenario: ...

Inject object into data attribute

I currently have data stored in a specific attribute like this: <div data-id=""> Within my markdown file, I also have a frontmatter variable like this: id: rick My goal is to pass that variable into the data-id attribute, which only accep ...

Cordova - Fixed elements flicker/blink when scrolling

I have exhausted all possible solutions, ranging from -webkit-transform: translate3d(0,0,0); to -webkit-backface-visibility:hidden but none of them seem to resolve the issue of an element flickering/blinking/disappearing when scrolling on iOS with - ...

Display all data using JSONP

I've encountered an issue with JSONP. Although I was able to successfully load my JSONP data into my html file, I am struggling to display all the information. I have attempted using both a for loop and $.each method without any luck. Here is the JSO ...

What are some strategies for minimizing code repetition when implementing login functionality across various OAuth2 providers?

Currently, I am utilizing various node modules such as Node.js, Express, Passport, and Mongoose. When a user clicks on "sign in with provider", there are two scenarios to consider. Let's take an example of using GitHub Strategy: 1. If the user is al ...

Passing data from the controller to the $resource object in Angular with the MEAN stack

After several attempts to troubleshoot my issue with passing parameters to the Express server, it turns out the problem lies on the Angular side. When I manually inserted the id in the flConstruct.js function, the query worked correctly. It appears that ...

Can you explain the distinctions among <Div>, <StyledDiv>, and <Box sx={...}> within the MUI framework?

When exploring the MUI documentation, I came across a table of benchmark cases that can be found here. However, the differences between the various cases are not clear to me. Can someone please explain these variances with real examples for the following: ...

Showing a div element with the power of JavaScript

I want to enhance the accessibility of my website for users who do not have JavaScript enabled. Content that will be visible if the user has JavaScript enabled. Content visible when JavaScript is disabled. By default, DisableJS is set to Display:none; ...

The ng-repeat directive adds an additional line after each iteration of the list item

Whenever the angular directive ng-repeat is utilized with an <li> element, I notice an additional line appearing after each <li>. To demonstrate this issue, see the simple example below along with corresponding images. Here is a basic example ...

How can I style the options and optgroups of a select dropdown with CSS, focusing on padding and margins?

In my experience, I have found that padding or margin CSS properties only seem to affect the appearance of options within the select menu in Firefox browser. I attempted the same styling in Internet Explorer and Chrome but it did not have any effect. Is ...

When setting a value through the DOM, the input's value bound with ngModel in Angular does not get updated

Trying to upload a file to calculate its hash and display it in an input box. If done correctly, the value should show in the form, but when submitting the form, the value does not get sent. Only adding a blank space by clicking on the input field works: ...

Checking the validity of a username through regex

I have implemented a Username field validation in Vue using regex. A key down event triggers the method below with each keystroke: userNameValidation(event) { if (!event.key.match(/^[a-zA-Z0-9._]+$/)) { event.preventDefault(); } ...

The challenge of Vue.js caching: NPM Build fails to update hash for single page application Vue.js app on Production server with Nginx

We currently have a Vue.js version 2.6.40 application running as a Single Page Application (SPA) with Laravel serving as the backend API. When we execute the npm run build command, it outputs files to dist/* directory with consistent hash values for each f ...

Tips for initiating a browser file download using JavaScript, ensuring that the download is only carried out if the web service responds with

For a project I am working on, I need to create JavaScript code that will be triggered by clicking on an <a> element. This code will then make a GET request to a web service that I am currently in the process of coding. Once the service returns a fil ...

Tips for utilizing the @run-at document-start meta-rule

Currently, I am utilizing the following code snippet: Jquery(window).load(function(){ // here is my code for making an AJAX request to retrieve data from the database }); Unfortunately, I have encountered an issue specifically with its function ...

Can you explain the functionality of this particular line of code in JavaScript?

As I continue to practice my coding skills, despite still being relatively new, I often come across this type of code in loops when searching for solutions to practice problems. I am intrigued by what exactly this particular line of code is accomplishing. ...

What could be the reason for encountering a TypeError while attaching event listeners using a for loop?

When attempting to add a "click" event listener to a single element, it functions correctly: var blog1 = document.getElementById("b1"); blog1.addEventListener("click", function(){ window.location.href="blog1.html"; }); However, when I try to use a for l ...

Manipulate JSON data in a Node.js loop

Currently, I am working on a monitoring system that will indicate on a website whether a server is up or down. I have experimented with various methods such as regex and replacement to modify the JSON file. My main objective is to dynamically change the "s ...