Insert element type date in an array every determined number of elements

0

I'm trying to insert a string which is a date every 5 elements that are generated dynamically.

const utils = require('./utils');
const moment = require('moment');
const flatpickr = require('flatpickr');
const Spanish = require('flatpickr/dist/l10n/es.js').default.es;

var urlBase = '';

if (location.hostname === "localhost") {
urlBase = '******* URL ********'; //Hide url for security ;)
}

module.exports = class Sms {

constructor(){
    var _this = this;
    this.noWeekend = false;
    this.typeCalendar = 'range';
    this.allDaysRange = [];
    this.allDatesRange = [];
    this.data = [];
    this.sms = {
        state: '',
        year: 0,
        month: 0,
        day: 0 
    };

    //Select for the states
    this.selectStates = document.querySelector('#ubicacion');
    this.selectStates.onchange = e => {
        if(e.currentTarget.value !== 'nacional'){
            this.noWeekend = true;
            this.dateInput.clear();
            this.dateInput.set('mode', 'multiple');
        }else{
            this.noWeekend = false;
            this.dateInput.clear();
            this.dateInput.set('mode', 'range');
        }
    }

    //Button search
    document.querySelector('.container-filter button')
            .addEventListener('click', () => {
                //this.allDatesRange = [];
                this.getDataSms();
            });

    //Config calendar
    this.dateInput = flatpickr('#date-sms', {
        maxDate: 'today',
        minDate: moment().subtract(1, 'years').format("YYYY-MM"),
        locale: Spanish,
        mode: _this.typeCalendar,
        firstDayOfWeek: 1,
        // onReady: function(){
        //     if(_this.noWeekend) return _this.dateInput.set('mode', 'multiple')
        //     //else return _this.dateInput.set('mode', 'range');
        // },
        onOpen: function(){
            if(_this.selectStates.value !== 'nacional'){
                return _this.noWeekend = true;
            }else{
                return _this.noWeekend = false;
            }
        },
        onChange: function(selectedDates){
            let daysRange = selectedDates.map(days => this.formatDate(days, "d"));
            let datesRange = selectedDates.map(dates => this.formatDate(dates, "m/Y"));

            //Get all days of range
            let startDay = Number(daysRange[0]);
            let endDay = Number(daysRange[1]);

            if(startDay > 0 && endDay > 0){
                for (let day = startDay; day <= endDay; day++) {
                    let i = 0;
                    if(day < 10) day = '0' + day;
                        _this.allDaysRange.push(day.toString());
                        _this.allDatesRange.push(day + '/'+ datesRange[i++]);
                }
            }

            console.log(_this.allDatesRange);
        },
        onClose: function(selectedDates){
            //Clean the dates container
            _this.allDatesRange = [];
        },
        defaultDate: [
            moment().subtract(1,'days').format("YYYY-MM-DD"),
            moment().format("YYYY-MM-DD")
        ],
        disable: [ //Get the news only the current month
            function (date) {
                if (_this.dateInput) {
                    return _this.dateInput.currentMonth != date.getMonth();
                } else {
                    var today = new Date();
                    return date.getMonth() != today.getMonth();
                }
            },
            function(date) {
                var element = document.getElementById('date-sms');
                var value = element ? element.value : '';
                if (value == '' || value.split(' a ').length == 2) {
                    return false;
                } else {
                    var initDate = moment(value, 'YYYY-MM-DD');
                    return date.getMonth() != initDate.month();
                }
            },
            function(date){
                //Disable Weekends
                if(_this.noWeekend) return !(
                                        date.getDay() === 1 ||
                                        date.getDay() === 2 ||
                                        date.getDay() === 3 ||
                                        date.getDay() === 4 ||
                                        date.getDay() === 5 
                                    )
            }
        ],
    });

    this.initialDataSms();
}


initialDataSms(){
    let date = moment();
    document.querySelector('.container-resultados h3').innerHTML = date.format('DD/MM/YYYY');

    //Params off request
    this.sms.year = date.year();
    this.sms.month = date.format('MM');
    this.sms.day = date.format('DD');
    this.sms.state = 'nacional';

    let file = '${this.sms.state}-${this.sms.year}-${this.sms.month}-${this.sms.day}.json';
    let url = '${urlBase}json/sms/${this.sms.state}/${file}';
   
    //GET the national sms
    utils.get(url)
        .then(response => {
            console.log(response.noticias);
            this.data = response.noticias;
            this.showContent(this.data);
        })
        .catch(err => {
            //Get national sms from one day before
            if(err.status == 404){
                let today = this.sms.day;
                    today -= 1;
                
                if(today < 10) today = '0' + today;
                    file = '${this.sms.state}-${this.sms.year}-${this.sms.month}-${today}.json';
                    url = '${urlBase}json/sms/${this.sms.state}/${file}';

                //Get national sms
                utils.get(url)
                    .then(response => {
                        this.data = response.noticias;
                        this.showContent(this.data);
                    })
                    .catch(err => console.log(err));
            }  
        });
}

/* EL ERROR ESTA EN ESTE MÉTODO */ 
getDataSms(){
    //Calendar input
    let inputDate = document.getElementById('date-sms');

    //Search params
    let state = document.getElementById('ubicacion').value;

    let dateInit, dateEnd;

    if(!this.noWeekend){
        dateInit = moment(inputDate.value.split(' a ')[0]);
        dateEnd = moment(inputDate.value.split(' a ')[1]);
    }else{
        dateInit = moment(inputDate.value.split(',')[0]);
        dateEnd = moment(inputDate.value.split(',')[1]);
    }
        
    //Params off request
    this.sms.month = dateInit.format('MM');
    this.sms.year = dateInit.year();
    this.sms.state = state;

    //Get the total items      
    let totalData = this.allDaysRange.map(async (item, i) => {
    
        let file = '${this.sms.state}-${this.sms.year}-${this.sms.month}-${item}.json';
        let url = '${urlBase}json/sms/${this.sms.state}/${file}';

        return utils.get(url)
                .then(response => response.noticias.map(async res => {
                    this.data[url];
                    this.data.push(res)
                }))
                .catch(err => console.log(err));
    });
    
    //Waiting for the the total http request finished 
    Promise.all(totalData).then(success => {
        console.log(this.data)
        this.showContent(this.data);
    });     
    console.log(this.data)
    
    //Clean the range and the data container
    this.allDaysRange = [];  
    this.data = [];      

    //Clean the calendar
    this.dateInput.clear();

    //document.querySelector('container-resultados > h3').css.display('none');
}

showContent(items){
    let container = document.querySelector('.container-resultados .section-search');
    let legend = document.querySelector('.container-resultados h3');
    
    console.log(this.data);

    if(items.length < 1){
        container.innerHTML = '<h3>No se encontraron resultados</h3>';
    }
    else {
        container.innerHTML = '';
        if(!this.noWeeken) legend.style.display = 'none';
       
        let ul = document.createElement('ul');
            ul.classList.add('nodo');
    
        for(let i = 0; i < items.length; i++) { 
            let element = this.createItemSms(items[i]);
    
             if ((i % 5 === 0)) {
                 let date = '<div class="container-resultados">
                                 <h3>${this.allDatesRange[i]}</h3>
                             </div>';
                
                 ul.insertAdjacentHTML('beforeend', date);
            } 
            ul.appendChild(element); 
        }
      
        container.appendChild(ul);
        this.createHeaders();
    }
}

createHeaders(){
    let lista = document.querySelector('ul.nodo');
    
    for (let i in lista) {
        let element = lista[i];
        for(let m in this.allDatesRange){
            if (i % 5 == 0){
                let date = '<div class="container-resultados">
                                <h3>${this.allDatesRange[m]}</h3>
                            </div>';
                lista.insertAdjacentHTML('afterbegin', date);
            }
        }
    }

    console.log(lista)
}
  
createItemSms(item){
    return utils.createElement('
      <li>
        <a class="search-item" href="${item.fcLinkDetalle}">
          <img src="${urlBase + item.fcImgPrincipal}">
            <h2>
              ${item.fcTitulo}
            </h2>
        </a>
      </li>
    ');
}

}

The problem is that this.allDatesRange[] is a variable of type array whose length does not correspond to the length that the for runs. Therefore it only shows the first element correctly and the others only shows undefined . Any comments or help is welcome, thanks.

    
asked by Alejandro Sánchez 08.12.2018 в 01:42
source

2 answers

0

What you should do is create a variable that will help you iterate in allDatesRange []

Here is an example code that I hope will inspire you:

var items = [];
for (i = 0; i < 50; i++) {
      items.push(i) // le agrego 50 elementos al array items
    }

var allDatesRange = [];
for (i = 100; i < 110; i++) {
  allDatesRange.push(i) // le agrego 10 elementos al array allDatesRange comenzando por el número 100, para diferenciar los arrays
    }


var itemsLenght = items.length; 
var allDatesRangeLenght = allDatesRange.length;
var allDatesRangeIndex = 0;

for (var i = 0; i < itemsLenght; i++) {
    console.log(items[i]);
    if ( ( i > 0 ) && //si i es mayor a cero
         ( i % 5 == 0 ) &&  // y cada 5 iteraciones
         ( allDatesRangeIndex <= allDatesRangeLenght )) {// y si esta dentro del tamaño de allDatesRange 
      console.log(allDatesRange[allDatesRangeIndex])
      allDatesRangeIndex++ // incremento el indice de allDatesRange
    }
}

If you have any questions do not hesitate to consult, I hope it serves you.

    
answered by 08.12.2018 в 03:02
0

Here is the solution for whoever is useful to you.

let ul = document.createElement ('ul');             let allDatesRangeLength = this.allDatesRange.length;             let allDatesRangeIndex = 0;

        for(let i = 0; i < items.length; i++) { 
            let element = this.createItemSms(items[i]);

            if (
                i % 5 == 0 && 
                allDatesRangeLength > 0 &&
                allDatesRangeIndex <= allDatesRangeLength
               )
               {
                    let date = '<li class="container-resultados">
                                    <h3>${this.allDatesRange[allDatesRangeIndex]}</h3>
                                </li>';

                    allDatesRangeIndex === 0 
                        ? ul.insertAdjacentHTML('afterbegin', date)
                        : ul.insertAdjacentHTML('beforeend', date)
                    allDatesRangeIndex++;
                } 

            ul.appendChild(element); 
        }

In the first round allDatesRangeIndex is equal to zero. Therefore placed the title before the children, later placed the title after the first 5 children. So the title corresponds to the following 5 children and so on. (The children are the "li" in a list "ul"). Very useful when for performance reasons the use of jQuery or similar is not allowed.

    
answered by 11.12.2018 в 19:33