0

I am trying to return true or false from my custom popup class depending on whether the user clicks 'delete' or 'cancel'.

I've created the popup class and an init method to show the popup. The init method is just a template string to style the popup and add the buttons. I created a getResult() method and added some click event listeners to the cancel and delete buttons. In my app.js file, I instantiated a popup class and called the getResult() method and attempted to store the return value in variable 'decision'.

class Popup {
    constructor(title, message){
        this.title = title;
        this.message = message;
        this.container = document.querySelector('body');
    }

init(){
    const popup = `
        <div class="popup-wrapper">
            <div class="popup bg-white p-1">
                <div class="popup-close">X</div>
                <div class="popup-content ">
                    <h2 class="">${this.title}</h2>
                    <p class="p-1 my-2">${this.message}</p>
                    <div class="dialogue_buttons my-1">
                        <button class="btn popup-no" onClick="">Cancel</button>
                        <button class="btn btn-danger my-1 popup-yes" onClick="">Start Delete</button>
                    </div>
                </div>
            </div>
        </div>  
    `;
    this.container.innerHTML += popup;
}

getResult(){
    document.querySelector('.popup-no').addEventListener('click', () => {
        console.log('no');
        return false;  
    })     
    document.querySelector('.popup-yes').addEventListener('click', () => {
        console.log('yes');
        return true;  
    })     
}

}

export default Popup

Below is my app.js file where i instatiate the popup.

 experienceTable && experienceTable.addEventListener('click', async e => {
  const id = e.target.parentElement.parentElement.getAttribute('data-id');
  if (e.target.tagName === 'BUTTON') {
    console.log(id);
    const confirmDelete = new Popup(
      'Delete', 
      'This will permanently delete this experience record.',
      ()=>db.deleteExperience(id),
      id
    );
    confirmDelete.init();
    const decision = await confirmDelete.getResult();
    console.log(decision);
  }
})

In my app.js file, I instantiated a new Popup and called the init method. The popup shows correctly in my browser. When I click cancel, it console logs "no" as expected. When I click Delete it console logs "yes" as expected. However, when i console log the variable decision, i get nothing. i expect decision to be true or false depending on which button the user clicked.

1
  • you can try solution I have provided and comment if you see any error. Commented May 11, 2019 at 7:02

2 Answers 2

2

I believe your getResult method isn't actually returning anything currently because the return statements are currently only in the scope of the callbacks, and then they are stuck at that level.

getResult(){
  let result = false;
  document.querySelector('.popup-no').addEventListener('click', () => {
    console.log('no');
  })     
  document.querySelector('.popup-yes').addEventListener('click', () => {
    console.log('yes');
    result = true;
  })
  return result;     
}

So here you are creating a variable, then in the callbacks you are assigning value to the variable and then returning that result.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the very quick reply! That logic does make sense and i've updated my code to reflect your edits. However, I still am not getting anything back for the decision in app.js. Also, I've noticed that the decision variable is getting printed immediately. It is not waiting for the return value from confirmDelete.getResult() even though i've made both functions in app.js and popup.js async. thoughts? I appreciate the help!
1

I can see you have attached button click event listners in getResult function. Side effects of this approach is that click event listners will be attached again and again when you call getResults method.

I have slightly improved your code and also attached callback parameter in case you want to do anything just after user's yes/no response.

I have attached event listeners in init method. Now, you can call getResults method explicitly or pass callback if you want to do automatically upon response.

class Popup {

  constructor(title, message, callback) {
    this.title = title;
    this.message = message;
    this.callback = callback;
    this.container = document.querySelector('body');
    this.result = '';
  }

  init() {
    const popup = `
        <div class="popup-wrapper">
            <div class="popup bg-white p-1">
                <div class="popup-close">X</div>
                <div class="popup-content ">
                    <h2 class="">${this.title}</h2>
                    <p class="p-1 my-2">${this.message}</p>
                    <div class="dialogue_buttons my-1">
                        <button class="btn popup-no" >Cancel</button>
                        <button class="btn btn-danger my-1 popup-yes" >Start Delete</button>
                    </div>
                </div>
            </div>
        </div>  
    `;
    this.container.innerHTML += popup;

    this.container.querySelector('.popup-no').addEventListener('click', () => this.cancelListner());
    this.container.querySelector('.popup-yes').addEventListener('click', () => this.startListner());

  }

  cancelListner(event) {
    this.result = 'no'
    if (this.callback !== undefined) {
      this.callback(this.result);
    }
  }

  startListner() {
    this.result  = 'yes';
    if (this.callback !== undefined) {
      this.callback(this.result);
    }
  }

  getResult() {
    return this.result;
  }

}

Hope this helps!

4 Comments

Abhishek, thank you for the code tweaks. Your edits make a a lot of sense as well and i've updated my code. However, i am still not getting anything for the decision variable in my app.js file when I call confirmDelete.getResult(). Seems like this should be an asynchronous task correct? Is there something wrong with the way I'm calling getResult() from app.js?
can you provide the jsfiddle or plunker of your code?. Also you have to click button cancel or start delete and then call getResults() method
Never made a jsfiddle before . Let me know if this works! Thanks . jsfiddle.net/khgriffi259/kt829q3f/9
I have played around with it a little and have solved my issue using your suggested callback Abhishek. The only thing I did was just remove the callback from the cancelListener and just dismiss the popup. In the the startListener method, I run the callback. Thank you for your help!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.