Home > Software engineering >  eventListener is firing multiple times before the refresh JS
eventListener is firing multiple times before the refresh JS

Time:12-18

I'm making a simple submit button for an email form,when clickling on the submit button and the email is valid,it changes the state of the button from "Subscribe" to Unsubscribe and it hides the form. Till here everything is good,but the problem is that when i click the submit button,it does what i need but after i enter a valid email and it changes the state of the button,the oposite action isnt done and it continues to send the email to localstorage,instead of removing it. Here i add a non valid email : enter image description here And in console log i have this email. Here i add a valid email without refreshing the page :

enter image description here

And now,when i click unsubscribe,it should remove the email from localStorage and return the form and the state of the button,but instead,it makes the submit action..: enter image description here

What should i do? I am new in JS and here i use only vanilla js.

The code that use the submit button:

document.querySelector('form').addEventListener('submit', function (e) {
e.preventDefault()
console.log(inputForm.value)
localStorage.setItem('Email', inputForm.value)
subscribeEmail(inputForm.value);
 })

The code below is used to mentain the state of the button when refreshing the page:

    const isSubscribed = localStorage.getItem('isSubscribed')
  if (isSubscribed === 'true') {
    subscribe()
    // document.querySelector('form').addEventListener('click', function (e) {
    //   e.preventDefault()
    //   unsubscribe()
    //   localStorage.removeItem('Email')
    // })
  } else {
    unsubscribe()
  }
}

Below is the code that changes the state of the button : Edit : I modified the code below and now i can unsubscribe without refreshing the page,the problem now is that i can not submit another value for validation and sending in localStorage.

  import { validateEmail } from './email-validator.js'


export const subscribe = () => {
    const subscribeBtn = document.getElementById('subscribeButton')
    subscribeBtn.setAttribute('value', 'Unsubscribe')
    document.getElementById('emailForm').style.display = 'none'
    localStorage.setItem('isSubscribed', 'true')
}

export const unsubscribe = () => {
    const subscribeBtn = document.getElementById('subscribeButton')
    subscribeBtn.setAttribute('value', 'Subscribe')
    document.getElementById('emailForm').style.display = 'block'
    localStorage.setItem('isSubscribed', 'false')
}


export const subscribeEmail = (email) => {
    if (validateEmail(email) == true) {
        subscribe();
        document.querySelector('form').addEventListener('click', function (e) {
            e.preventDefault()
            unsubscribe()
            localStorage.removeItem('Email')
        })
    } else if (validateEmail == false) {
        unsubscribe();
    }
};

And here is the validation function :

const VALID_EMAIL_ENDINGS = ['gmail.com', 'outlook.com', 'yandex.ru']

export const validateEmail = (email) => {
  if (VALID_EMAIL_ENDINGS.some(v => email.includes(v))) {
  return true
  } else {
  return false
  }
}

export { VALID_EMAIL_ENDINGS as validEnding }

I dont understand what is wrong,or is this normally to happen..It gives me the oportunity to "unsubscribe" only after refreshing the page,but i want to subscribe and unsubscribe multiple times without the need of refresh.

I should mention that the section where the button is created is displayed usign window.onload,so it is dinamically created.

Edit:

The whole section creation code:

import { subscribe, unsubscribe} from './subscribe.js'
import { subscribeEmail } from './subscribe.js'

const addSection = () => {
  const sectionFour = createElement('sectionFour', 'section', 'app-section app-section--image-program', 'fourth-section')
  const sectionParent = getElbyID('sectionParent', 'third-section')
  const parentSection = sectionParent.parentNode
  parentSection.insertBefore(sectionFour, sectionParent.nextSibling)

  const heading2 = createElement('heading2', 'h2', 'program-title')
  const heading2Text = document.createTextNode('Join Our Program')
  heading2.append(heading2Text)
  const parent = getElbyID('parent', 'fourth-section')

  const heading3 = createElement('heading3', 'h3', 'program-subtitle')
  const heading3Text = document.createTextNode('Sed do eiusmod tempor incididunt')
  heading3.appendChild(heading3Text)
  const linebreak = createElement('linebreak', 'br')
  heading3.appendChild(linebreak)
  const textAfterBreak = document.createTextNode('ut labore et dolore magna aliqua')
  heading3.appendChild(textAfterBreak)

  const form = createElement('submitFieldWrapper', 'form', 'submitFieldWrapper', 'form')
  parent.append(heading2, heading3, form)

  const emailForm = createElement('emailForm', 'div', 'form-wrapper', 'emailForm')

  const inputForm = createElement('inputForm', 'input', 'form-input', 'submit-info')
  setAttributes(inputForm,
    'type', 'text',
    'placeholder', 'Email')
  if (localStorage.getItem('Email') !== null) {
    inputForm.setAttribute('value', localStorage.getItem('Email'))
  } else {
    inputForm.setAttribute('placeholder', 'Email')
  }

  emailForm.appendChild(inputForm)

  document.querySelector('form').addEventListener('submit', function (e) {
    e.preventDefault()
    console.log(inputForm.value)
    localStorage.setItem('Email', inputForm.value)
    subscribeEmail(inputForm.value);
  })

  const submitForm = createElement('submitForm', 'input', 'app-section__button submit-btn', 'subscribeButton')
  setAttributes(submitForm,
    'type', 'submit',
    'value', 'Subscribe')
  form.append(emailForm, submitForm)

  const isSubscribed = localStorage.getItem('isSubscribed')
  if (isSubscribed === 'true') {
    subscribe()
    // document.querySelector('form').addEventListener('click', function (e) {
    //   e.preventDefault()
    //   unsubscribe()
    //   localStorage.removeItem('Email')
    // })
  } else {
    unsubscribe()
  }
}

const createElement = (elName, htmlEl, elClass, elID) => {
  const elementName = document.createElement(htmlEl)
  elementName.className = elClass
  elementName.id = elID

  return elementName
}

const getElbyID = (elName, searchedId) => {
  const elementToSearch = document.getElementById(searchedId)

  return elementToSearch
}

const setAttributes = (elem, ...elemArguments) => {
  for (let i = 0; i < elemArguments.length; i  = 2) {
    elem.setAttribute(elemArguments[i], elemArguments[i   1])
  }
}

export const advancedSection = () => {
  addSection()
  const getHeading = document.getElementById('fourth-section')
  const sectionChildren = getHeading.children
  sectionChildren[0].innerHTML = 'Join Our Advanced Program'
  const getButton = document.getElementById('subscribeButton')
  setAttributes(getButton,
    'type', 'submit',
    'value', 'Subscribe to Advanced Program')
  getButton.className = 'app-section__button submit-btnAdvanced'
}

export default addSection

And main.js

import addSection, { advancedSection } from './join-us-section.js'

class SectionCreator {
  constructor (type) {
    this.type = type
  }

  create (type) {
    if (type === 'standard') {
      addSection()
    } else if (type === 'advanced') {
      advancedSection()
    }
    return type
  }

  remove () {
    const sectionToRemove = document.getElementById('fourth-section')
    sectionToRemove.remove()
  }
}

window.onload = new SectionCreator().create('standard')

I managed how to do to unsubscribe without refreshing the page,but now the problem is that without refreshing i can not put another input.. This is how i did to unsubscribe without refreshing :

export const subscribeEmail = (email) => {
    if (validateEmail(email) == true) {
        subscribe();
        document.querySelector('form').addEventListener('click', function (e) {
            e.preventDefault()
            unsubscribe()
            localStorage.removeItem('Email')
        })
    } else if (validateEmail == false) {
        unsubscribe();
    }
};

This event listener was in isSubscribed function,but i moved it to subscribeEmail,where it checks the validatation.The code above may differ at the end because i renamed the variables,from unsubscribeToggle to isSubscribed,from getUnsubscribe to subscribe and from getSubscribe to unsubscribe

CodePudding user response:

Without seeing all your code it's hard to modify everything here, plus localStoage doesn't work in the snippets. See if this example helps. It uses just a bit of code to manage the subscribe vs unsubscribe functions without having to refresh the page.

// init code
let hasSubscribed = false
let userEmail = ''
let subBtnEl, inputEl, resultEl

window.addEventListener('DOMContentLoaded', () => {
  // userEmail = localStorage.getItem('email') || '';;
  subBtnEl = document.querySelector('button#sub');
  inputEl = document.querySelector('input[name=email]');
  resultEl = document.querySelector('#result');
  subBtnEl.addEventListener('click', e => {
    resultEl.innerText = "";
    doButton()
  })
})

function isValidEmail(email) {
  return true;
}

function doButton() {
  // check localStorage
  hasSubscribed = userEmail.trim() !== '';
  if (!hasSubscribed) {
    if (!isValidEmail(inputEl.value)) {
      resultEl.innerText = "Invalid Email";
      return
    }
    userEmail = inputEl.value;
    inputEl.setAttribute('hidden', true);;
    subBtnEl.innerText = "Unsubscribe";
    resultEl.innerText = "You've been subscribed!";
    // localStorage.setItem('email', subBtnEl.value.trim());
  } else {
    // localStorage.setItem('email', '');
    userEmail = '';
    inputEl.removeAttribute('hidden');;
    resultEl.innerText = "You've been unsubscribed";
    subBtnEl.innerText = "Subscribe";
  }
}
<div id='result'></div>
<input type='text' name='email' />
<button id='sub'>Subscribe</button>

CodePudding user response:

I managed how to unsubscribe without refreshing:

export const subscribeEmail = (email) => {
    if (validateEmail(email) == true) {
        subscribe();
        document.querySelector('form').addEventListener('click', function (e) {
            e.preventDefault()
            unsubscribe()
            localStorage.removeItem('Email')
        })
    } else if (validateEmail == false) {
        unsubscribe();
    }
};

I just played with functions and have put in their place.And i fixed the problem that i can not subscribe and unsubscribe a lot of times.
I should have just remove preventDefault in the function and change with a stopPropagation:

export const subscribeEmail = (email) => {
  const isValidEmail = validateEmail(email)
  if (isValidEmail === true) {
    subscribe()
    document.querySelector('form').addEventListener('click', function (e) {
      unsubscribe()
      localStorage.removeItem('Email')
      e.stopPropagation()
    })
  } else if (isValidEmail === false) {
    unsubscribe()
  }
}
  • Related