I am working on a Vue instance that fetches objects from a REST endpoint and showcases them on a web page. Most parts of the functionality work smoothly like filtering, however, there is an issue when attempting to add new objects by requesting a new "page" of results from the service. Unlike other operations, adding new results involves appending them to the existing set rather than replacing it entirely. The challenge arises as the service only provides the requested "page" of results. Here's the specific code snippet causing the issue:
// External server-side process handles these variables not within Vue context
let searchTags = ["tag1", "tag2", "etc"];
let productsBaseSearchTag = "a/b/c";
Vue.mixin({
methods: {
doSearchStuff: function(response, data) {
this.searchResponse = response;
this.resultCount = response.total; // jQuery used for consistent results display due to issues
jQuery(".search-page-sort-results .num").text(this.resultCount);
if (this.currentPage > 1) {
this.searchResults = this.searchResults.concat(data.hits);
} else {
this.searchResults = data.hits;
}
this.facetCount = data.facets.length;
}
}
});
new Vue({
el: '#v-search-page-results',
data: {
searchResponse: {},
searchResults: [],
facetHeaders: searchTags,
returnedFacetHeaders: undefined,
currentPage: 1,
hitsPerPage: 12,
searchTerm: "",
statusMessage: "",
sortProperty: "",
displayedFilters: {},
predicateList: [],
facetCount: 0,
resultCount: 0,
showLoading: true
},
created: function() {
this.predicateList = searchTags;
this.getSearchResults(false);
},
computed: {
pdpPaths: function() {
return this.searchResults.map(function(item) {
let catalogPath = item.path;
return decodeURIComponent(pdpPath) + catalogPath.replace(decodeURIComponent(catalogRoot), "").replace(/\//g, ".");
});
},
summaries: function() {
return this.searchResults.map(function(item) {
let summary = item.properties.summary;
if (summary.length >= 120) {
summary = summary.substring(0, 120);
summary = summary.substring(0, summary.lastIndexOf(" ")) + "...";
}
return summary;
});
},
assetAbsoluteURLs: function() {
return this.searchResults.map(function(item) {
let escapedUrl = item.path.replace(/\s/g, "%20");
return location.origin + escapedUrl;
});
},
canClearFilters: function() {
return this.predicateList !== searchTags;
},
moreResults: function() {
if (this.searchResponse) {
let resultCount = this.resultCount;
let totalLoadedResults = this.hitsPerPage * this.currentPage;
if (totalLoadedResults < resultCount) {
return true;
}
}
return false;
}
},
methods: {
loadMoreResults: function() {
this.currentPage += 1;
this.getSearchResults();
},
clearSearchTerm: function() {
this.searchTerm = "";
this.submitSearchTerm();
},
getSearchFilters: function() {
if (this.predicate...
Many complexities are addressed in the code section above regarding array operations. Furthermore, here's the corresponding HTML markup showcasing the array iteration using v-for:
<div id="v-search-page-results" class="search-page-container _clearfix">
<div class="search-page-wrapper">
<div class="search-page-facets-wrapper">
<div class="search-page-sort-results">
<span v-cloak class="num">{{ resultCount }}</span> results
</div>
</div>
<div class="search-page-container">
<!-- facet stuff here -->
<div class="search-page-results-container">
<div class="search-page-results-wrapper">
<div v-for="(result, index) in searchResults" class="search-page-results-item" v-bind:key="result.id">
<div class="search-page-image-container">
<img v-cloak :alt="result.title" :src="result.properties.thumbnailPath" class="search-page-image">
</div>
<div class="search-page-results-content">
<a v-cloak :href="pdpPaths[index] + '.html'" class="title" title="">{{ result.properties.productTitle }}</a>
<div v-cloak class="description" v-html="summaries[index]"></div>
</div>
</div>
</div>
<div class="search-button-top-nav">
<div v-show="moreResults" class="button-wrapper load-more-container load-more-wrapper">
<div class="button-wrapper-2">
<div class="button-container">
<a @click="loadMoreResults" class="btn -primary load-more">Load More</a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Lastly, shown below is an example of the data we aim to iterate through:
"hits": [
{
"id": 1,
"title": "product1",
"path": "/path/to/product1",
"properties": {
"thumbnailPath": "/products/images/product1.jpg",
"productTitle": "Product 1",
"summary": "<p>This is product 1.</p>\r\n"
}
},
{
"id": 2,
"title": "product2",
"path": "/path/to/product2",
"properties": {
"thumbnailPath": "/products/images/product2.jpg",
"productTitle": "Product 2",
"summary": "<p>This is product 2.</p>\r\n"
}
}
]
The attempts made include utilizing Vue.set, iterating over response objects while pushing one object at a time into the array, leveraging the spread operator, among others. The array does receive the new elements successfully, but Vue fails to reflect these additional results. Overwriting current objects within the array with new ones displays correctly, implying that the DOM updates but stops showing beyond a certain number of items. Despite trying several approaches, the desired outcome remains elusive.