1

I'm trying to get results from an api based on the user search box. When the user enters a value 'en' or 'de'. They should get the result from that search. I need to bind the user input into my query string. This works when I manually code the country into the template, but not when I bind the value into the string after the user inputs a value for the second time. The 'get' request that uses the user input value 'query' works fine. But not when I bind this a second time

I want to be fit to access results[i].query.name But '.query' is not working when I query the data unless I enter the value manually '.en'

I have a json file that looks like the following

    [
      {
        "en": {
          "name": "testone",
          "id": 5363289,
          "location": "messages_en.properties1"
        },
        "de": {
          "name": "testonede",
          "id": 5363289,
          "location": "messages_en.properties2"
        }
      },
      {
        "en": {
          "name": "test2",
          "id": 5363289,
          "location": "messages_en.properties3"
        },
        "de": {
          "name": "test2de",
          "id": 5363289,
          "location": "messages_en.properties4"
        }
      }
   ]

Below is my index.html vue.js template

<div id=#app>

<input type="text" v-model="query" placeholder="Choose Language" />

  <div class="medium-6 columns">
    <a @click="getResult(query)" class="button expanded">Retrieve</a>
  </div>

<template v-for="(result, i) in results">
              <div  class="card" style="width: 20rem; display:inline-block;">
                <div class="card-block"></div>

                <p> {{results[i].query}} </p>

                <!-- works when I manually code in the 'en' query but when ran with 'query' it returns an error 'Cannot read property 'name' of undefined"' second time it returns that the value is  -->
                <!-- <p> {{results[i].en.name}} </p> -->
                <!-- <p> {{results[i].query.name}} </p> -->

                </div>   
     </template>
</div>

Vue.js

el: '#app',
    data () {
      return {
      search: '',
      query: 'en',
      results: '',
      title: '',
      items: '',
      section: ''
      }
    },
    methods: {
      getResult(query) {
        axios.get('http://localhost:3000/api/country?country=' + query + '&blank=true').then(response => {
        this.results = response.data;
        console.log(this.results);
        });
      },
  • 2
    You need to do: `results[i][query].name` – craig_h Jan 14 '18 at 11:29
  • Possible duplicate of [Dynamically access object property using variable](https://stackoverflow.com/questions/4244896/dynamically-access-object-property-using-variable) – yuriy636 Jan 14 '18 at 11:29
  • When I console.log(this.query); I get the correct result each time. But how can I pass this to the index query string {{results[index].query.name}} without fail? I get name as undefined. When I bind {{query}} I get the correct result and when I bind {{results[i]}} but I want to be able to bind the query also – themanwiththemasterplan Jan 14 '18 at 11:31
  • @craig_h Thank you, this is what I was looking for. But now as I'm entering a new query in the search box, as I'm typing I get an error '[Vue warn]: Error in render: "TypeError: Cannot read property 'name' of undefined"' before I submit the button. But when I submit the data is fine – themanwiththemasterplan Jan 14 '18 at 11:37

1 Answers1

1

You need to use bracket notation to access a property using a param, so:

results[i][query].name

The second issue is that results[i][query] will be undefined until the async call has completed, so you will need to check that the property is not undefined or use a boolean flag. So, to check that it is not undefined you could do something like:

<p v-if="!!results[i][query]">{{results[i][query].name}}</p>
<p v-else>Loading...</p>

Here's a simplified JSFiddle for that: https://jsfiddle.net/4w3dxm22/

Or you could just use a dataLoaded flag:

new Vue({
  el: '#app',
  methods:{
    getResult(query) {
      this.dataLoaded = false; // set dataLoaded to false
      axios.get('http://localhost:3000/api/country?country=' + query + '&blank=true').then(response => {
      this.results = response.data;
      this.dataLoaded = true; // Data has loaded so set dataLoaded to true
    });   
  },
  data: {
    dataLoaded: false
  }
})

Then you can do:

<span v-if="dataLoaded">{{results[i][query].name}}</span>
<span v-else>Loading Data...</span>

Here's the simplified JSFiddle for that: https://jsfiddle.net/99ydx82u/

craig_h
  • 31,871
  • 6
  • 59
  • 68