I'm trying to figure out why my results are being duplicated in my vue code
Basically, I'm just taking numbers from one object (which shows the amound of products being produced at a warehouse on given dates) then comparing those results to another object (which shows amount of products that are allowed to be produced on each day)
I'm color-coding based on a comparison, but the issue is that I'm getting multiple results of each warehouse per day when I should be getting only one per warehouse like so:
2021-11-13 | 2021-11-14 | 2021-11-15
----------------------------------------------------------------
Warehouse 1: 200 Warehouse 1: 200 Warehouse 1: 200
Warehouse 3: 10000 Warehouse 3: 10000 Warehouse 3: 10000
Why am I getting multiple entries for each warehouse on each day?
const warehouseNest = (rows) =>
rows .reduce(
(b,row) => {
const warehouseIndex = b [row .warehouse] || (b [row .warehouse] = {dates: {}})
const date = warehouseIndex .dates [row .date] || (warehouseIndex .dates [row .date] = {qty_for_date: 0})
date.qty_for_date = row.qty
return b
},
{}
);
var vm =
new Vue({
el: "#app",
data: {
rows:[
{
date: "2021-11-09",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-10",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-11",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-12",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-13",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-14",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-15",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-16",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-17",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-18",
qty: 37,
warehouse: "1"
},
{
date: "2021-11-09",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-10",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-11",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-12",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-13",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-14",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-15",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-16",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-17",
qty: 37,
warehouse: "3"
},
{
date: "2021-11-18",
qty: 37,
warehouse: "3"
}
],
available:[
{
"location":"1",
"date":"2021-11-09",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-10",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-11",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-12",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-13",
"product_avail":"10000"
},
{
"location":"1",
"date":"2021-11-14",
"product_avail":"10000"
},
{
"location":"1",
"date":"2021-11-15",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-16",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-17",
"product_avail":"200"
},
{
"location":"1",
"date":"2021-11-18",
"product_avail":"200"
},
{
"location":"3",
"date":"2021-11-09",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-10",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-11",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-12",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-13",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-14",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-15",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-16",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-17",
"product_avail":"10000"
},
{
"location":"3",
"date":"2021-11-18",
"product_avail":"10000"
}
]
},
computed: {
dateNumberData(){
dateRows = warehouseNest(this.rows)
return dateRows
},
dates() {
return Array.from(Array(11), (_, i) => new Date(Date.now() i * 86400000).toISOString().slice(0,10))
},
activelocation: function() {
return this.available.filter((location) => {
if (this.dates.includes(location.date)) {
return location
}
})
},
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<table>
<th v-for="date in dates" :key="date" >
<div v-for="(value, location) in dateNumberData" :key="location">
<div v-for="(specificValues, dateValue) in value.dates" :key="dateValue">
<div v-if="dateValue == date ">
<div v-for="location in activelocation" v-if="dateValue === location.date" :style="'background: ' (specificValues.qty_for_date > location.product_avail ? '#f7a7a3' : '#a8f0c6')">
<h4 style="display:inline-block; font-weight: bold;">Warehouse {{location.location}}</h4>: {{location.product_avail}}
</div>
</div>
</div>
</div>
</th>
</table>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
It looks like you're iterating all possible locations twice,
Once here:
<div v-for="(value, location) in dateNumberData" :key="location">
Then again here:
<div v-for="location in activelocation" v-if="dateValue === location.date" :style="'background: ' (specificValues.qty_for_date > location.product_avail ? '#f7a7a3' : '#a8f0c6')">
Hence they are listed twice.
You would need to filter the inner iteration of locations with the location you're currently iterating in the outer one.
For example, the inner loop condition now includes && outerLocation === location.location
, and I've renamed the outerLocation
so it's not clashing with the location
on the inner loop.
<div v-for="(value, outerLocation) in dateNumberData" :key="outerLocation">
<div v-for="(specificValues, dateValue) in value.dates" :key="dateValue">
<div v-if="dateValue == date ">
<div v-for="location in activelocation" v-if="dateValue === location.date && outerLocation === location.location" :style="'background: ' (specificValues.qty_for_date > location.product_avail ? '#f7a7a3' : '#a8f0c6')">
<h4 style="display:inline-block; font-weight: bold;">Warehouse {{location.location}}</h4>: {{location.product_avail}}
</div>
</div>
</div>
</div>
I think that should resolve your immediate problem, though fundamentally the complexity of this code is too high to reason about easily and would probably benefit from refactoring.