Home > Software design >  How to create new object with limited data from other object in Vue JS
How to create new object with limited data from other object in Vue JS

Time:02-02

I am trying to create a search app that looks for products. I’ve got a PHP script that returns results in JSON format when a keyword is posted to it. I post to there with axios.

Now if there are 40 results for example the dropdown of results will be too long. So I want to create a new object from the object of 40 results and limit this object to 6.

I tried this by creating a function inside computed like this:

Object(this.responseData) is my full object with all results from my PHP script in a JSON object. filteredData is my new object that I added in my data.

test(){
    var fullResults = Object(this.responseData);
    var number = 0;
    for (var key in fullResults) {
        number  ;
        if(!number > 6){
            this.filteredData[number]  = fullResults[key]
        }
    }
    console.log(this.filteredData)
},

But my log just shows: Proxy {}. What am I doing wrong? I need to get all results from the old object, and add them to a new empty object with a limit of 6.

This is my full JS:

let app = Vue.createApp({
    data: function(){
        return{
            // Object to fill with JSON response
            responseData:{},
            // Object to fill with filtered result (max 6)
            filteredData: {},
            showResultDiv: false,
            totalResults: 0
        }
    },
    methods:{
        // Function to show loading dots until json returned
        loadDiv(condition, content){
            this.showResultDiv = condition
        },
        async fetchResults(){
            await axios.post('includes/searchproducts_json.php', {
                // Post data, add value of input to searchterm
                searchterm: this.$refs.searchterm.value
            })
            .then((response)=>{
                this.responseData = response.data
                // Get length of returned object and add to totalResults
                this.totalResults = Object.keys(this.responseData).length
                console.log(Object(this.responseData));
            })
            .catch((error)=>{
                console.log(error)
            })
        }
    },
    computed: {
        filteredObject(){
            return this.responseData
        },
        test(){
            var fullResults = Object(this.responseData);
            var number = 0;
            for (var key in fullResults) {
                number  ;
                if(!number > 6){
                    this.filteredData[number]  = fullResults[key]
                }
            }
            console.log(this.filteredData)
        },
        // Set totalResults with matching string
        resultString(){
            if(this.totalResults == 1){
                return this.totalResults   ' resultaat'
            }else{
                return this.totalResults   ' resultaten'
            }
        }
    }
})

app.mount('#v_search');

CodePudding user response:

Object.keys() returns an array of the object keys, which could be the thing you are looking for if i understand correctly. Then you could create a computed property something like this:

test() {
   return Object.keys(this.responseData).map((key) => this.responseData[key]).slice(0,6);
}

This transforms the object to an an array after which you can use a simple slice method to get the first 6 elements.

CodePudding user response:

Your search result set should really be an array (of result objects).

Something like:

[
  {"id": 1, "text": "foo"},
  {"id": 2, "text": "bar"},
  {"id": 3, "text": "baz"},
  ...
]

Or, more elegant:

{
  "searchterm": "input value"
  "total_results": 31,
  "limit": 10,
  "page": 2,
  "results": [
    {"id": 1, "text": "foo"},
    {"id": 2, "text": "bar"},
    {"id": 3, "text": "baz"},
    ...
  ]
}

Then, the computed should be as simple as:

data() {
  return {
    results: []
  }
},
computed: {
  resultsToShow() {
    return this.results.slice(0, 6)
  }
},
methods:{
  fetchResults() {
    axios.post('includes/searchproducts_json.php', {
      // Post data, add value of input to searchterm
      searchterm: this.$refs.searchterm.value
    })
    .then((response) => {
      if (response.status === 200 && response.data.length) {
        this.results = response.data
      }
    })
    .catch(console.error)
  }
}

See a working demo: https://codesandbox.io/s/thirsty-germain-i6w4w?file=/src/App.vue

  •  Tags:  
  • Related