0

Good evening, I have searched for the problem I'm having for quite some time and haven't seen an answer or post close enough to extract useful help.

I am retrieving some dates from Firebase that I would like to populate into some ui elements in my Vue app. the ultimate goal is to get each date that comes from Firebase to match with the corresponding month in the Vue app and fill those ui elements. So far, I am having trouble getting the data to show in properly at all without causing an infinite loop warning.

Here is the code so far below:

data() {
    return {
      dates: [], <---- dates will fill this array from Firebase
      months: [ 
       {name: 'Jan', createdOn: [] }, 
       {name: 'Feb', createdOn: [] }, 
       {name: 'Mar', createdOn: [] }, 
       {name: 'Apr', createdOn: [] }, 
       {name: 'May', createdOn: [] }, 
       {name: 'Jun', createdOn: [] }, 
       {name: 'Jul', createdOn: [] }, 
       {name: 'Aug', createdOn: [] }, 
       {name: 'Sept', createdOn: [] }, 
       {name: 'Oct', createdOn: [] }, 
       {name: 'Nov', createdOn: [] }, 
       {name: 'Dec', createdOn: [] }, 
     ]
    };
},
methods: {
 logNewDate() {
  let mons = this.months
  let dates = this.dates
  dates.forEach(date => {
    if(!mons[0].createdOn.includes(dates)) {
     mons[0].createdOn.push(date.createdOn)
    }
  })
    console.log(mons[0].name, mons[0].createdOn)    
 },
}
<div v-for="month in months" :key="month.name">
    <b-button 
    class="btn-circle btn-md" 
    >
      {{ month.name }}
    </b-button>
</div>
    {{ logNewDate() }}

At first the I had the months array as an array or month strings, but this simply caused all the dates in firebase to loop repeatedly for each month creating 5 ui elements each time but no infinite loops initially. I figured the next step was to have an array collection included with the name of the month so that i could store multiple dates from the same month together, so idea with the months property shown above in the data function is to match the incoming data with the proper month name and fill that objects createdOn array with the matching dates.

So far the forEach loop in my logNewDate function will store all the dates that show from Firestore (only 5 right now for testing purposes) but once all five show it loops back through and adds all five dates again over and over. At first I used a for in loop that iterated the dates array and added each date to the createdOn array, but this caused an infinite loop too which makes me think there's a more fundamental issue with my approach in this code.

After some researching around, I tried using a if(mons[0].createdOn.includes(date)) check to only include dates that hadn't shown up yet and no others, but that didn't work. I also tried adding break in the loop with no effect either. the function that retrieves the Firebase data is currently in my created lifecycle method. I'd only like this to happen once for what I'm testing right now. Can someone help me understand what's causing the loop and how to fix it and prevent these errors going forward?

I'd also like to note that I realize hardcoding the array indexes in the forEach loop isnt the best practice. I ultimately want that to be dynamic, equating with the month of the date from Firebase. I hardcoded them in my example for testing purposes.

the errors are show below: enter image description here

enter image description here

9
  • Please share the complete code and also add the error you are getting, So that we can help you more. Commented Nov 8, 2021 at 3:26
  • 1
    Your if(!mons[0].createdOn.includes(dates)) is not checking for the thing that's being pushed, so I don't think that will prevent dups. Commented Nov 8, 2021 at 3:28
  • I'm guessing a bit at the overall problem. Maybe you're responding to a data change notification by altering data. Altering the data would cause a data change notification, and hence infinite loop. Commented Nov 8, 2021 at 3:30
  • You actually helped me out a ton with your first comment. I wasn't accessing the dates in my includes function. Once i did that I got the dates I expected with no infinite loops. However it does still print 2 arrays in the console which I'm not sure why. Commented Nov 8, 2021 at 3:33
  • You mean you don't know why logNewDate is being invoked twice? I don't know Vue.js but I guess it has something to do with the way it renders. Commented Nov 8, 2021 at 3:45

1 Answer 1

1

Prabir made a great point. The solution that worked for me involved using nested for-in loops.

Once I was in the inner loop where I access my incoming dates, I convert the date strings into date object, shorten those strings to the shortened month name, and then use === to check if those new month strings match the ones I have preset in my month object.

This is my final code:

for(let i in this.months) {
    for(let j in this.incomingDates) {
        var dates = new Date(this.incomingDates[j].createdOn);
        const shortMonth = dates.toLocaleString('default', { month: 'short' });
        if(shortMonth === this.months[i].name) {
            this.months[i].createdOn.push(shortMonth);
            console.log(this.months[i].name, this.months[i].createdOn);
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.