Flight Search Axios

Looking to create two inputs that when provided a keyword will get airport name from the database and display it under the input itself.

So far with the code below I managed to achieve this for the first input by making GET request to the database, however when I input a keyword in the second input the result under first one gets overwritten.

Could anyone advise what do I have to do that for each input the searchAirport() method is run separately and the result of each input is written underneath without overwriting each other?

<template>
   <div class="pairing-search">

       <div class="airport-input">
           <input type="text" v-model="From" @keyup="airportSearch">
           <ul v-if="Airports.length > 0">
               <li v-for="airport in Airports" :key="airport.id">{{ airport.name }}&nbsp;({{ airport.gps_code }})</li>
           </ul>
       </div>

       <div class="airport-input">
           <input type="text" v-model="To" @keyup="airportSearch">
<ul v-if="Airports.length > 0">
               <li v-for="airport in Airports" :key="airport.id">{{ airport.name }}&nbsp;({{ airport.gps_code }})</li>
</ul>

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

<script>
   export default {
       name: "PairingSearch",
       data() {
           return {
               From: null,
               To: null,
               Airports: []
           };
       },
       methods: {
           airportSearch() {
               axios.get('/searchairport', {
                   params: { keyword: this.From }
               })
               .then(res => this.Airports = res.data)
               .catch(error => {});
           },
       }
   }
</script>

Not sure how you intend for this to work in a finished product. It seems to me that the best option for an airplane travel thing would be to show flights out of a (lets use ‘terminal’) when someone inputs the location, then when the second input is added, the “to” it would be a filtered list of going from and to.

I could suggest two different routes. If you have no pagination, I would suggest a simple way would be to get the initial values from “from” terminal, then in your second input you could actually just use filter on the already existing data that you got from the “from”. Just do an array.filter based on the “to” category. That way you don’t need to send additional requests since the data you need already exists.

Though, second option would be to make the request and have it send the data back from the backend. I’d just do the same get request, just add in the “to” destination onto the body of the request. Fairly simple.

If you wanted separate results, I would just make two methods and two different return values. No need to overbear a method with multiple objectives. “Single responsibility rule” and all that.

Let me know what idea you think works best. There’s a couple different ways to implement what you want, with pros and cons to each. It really just depends on the end goal you want.

But to conclude easily, if you wanted separate results for the two inputs, then you should just make two separate methods and return values.

1 Like

Many thanks for your reply Issayah! This is the kind of answer I am looking for.

The list of airports and their details is stored in a table in a MySQL database, that is where I am calling the GET request to retrieve the gps_code for example.

Due to my limited knowledge, I could only implement your second suggestion which works perfectly:

<template>
    <div class="pairing-search">
        <div class="airport-input">
            <input type="text" v-model="from" @keyup="departureSearch" autocapitalize="characters" >
            <ul v-if="depAirport.length > 0">
                <li v-for="airport in depAirport" :key="airport.id" >{{ airport.gps_code }}</li>
            </ul>
        </div>

        <div class="airport-input">
            <input type="text" v-model="to" @keyup="arrivalSearch" >
            <ul v-if="arrAirport.length > 0">
                <li v-for="airport in arrAirport" :key="airport.id">{{ airport.gps_code }}</li>
            </ul>
        </div>
    </div>

</template>

<script>
export default {
    name: "PairingSearch",
    data() {
        return {
            from: null,
            to: null,
            depAirport: [],
            arrAirport: [],
            airports: []
        };
    },
    methods: {
       departureSearch() {
            axios.get('/searchairport', {
                params: { keyword: this.from }
            })
            .then(res => this.depAirport = res.data)
            .catch(error => {});
        },
        arrivalSearch() {
            axios.get('/searchairport', {
                params: { keyword: this.to }
            })
            .then(res => this.arrAirport = res.data)
            .catch(error => {});
        },
    }
}
</script>

However, I am intrigued by your initial suggestion which to my understanding would make only one call to the database and retrieve all airports which are then filtered to get only the one I need based on my input, right? If so - could you perhaps assist with altering the code above to reflect your first solution?

going to be a bit crude and not well organized

data() {
   return {
       from: null,
       to: null,
       airports: []
     }
},
methods: {
   departureSearch() {
      axios.get('/searchAirport', {
          params: { keyword: this.from }
      }).then(res => this.airports = res.data).catch(err => {})
},
computed: {
    searchResults () {
      if(this.to) {
          return this.airports.filter(item)=>{
              return this.to.toLowerCase().split(' ').every(v => item.destination.toLowerCase.includes(v))
          })else{
             return this.airports
          }
    } 
}

It’s kind of complicated array methods… And it may not exactly work how you want because even I’m a little confused as to what’s happening, as it’s a lot of chaining and nested methods… But the premise is, if you have no “this.to”, it will just return all airports. If there is a “to” it will filter through, based on if the “destination” (I don’t know if destination is the actual key for the object here. If it doesn’t work out of the box, try changing the key, and if it still doesn’t work, at least it’s a good starting point.) but it filters through the destination and returns a filtered list.

All you would have to do after is to

<li v-for="airport in searchResults" ... />

Instead of the airports array itself