Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript - Push function to array, loop through and remove after executed

I am trying to create an array that holds all pending error messages that shows up on the DOM (Using jquery for that) and then loop through the array to see if there is any error messages to call, and if so remove them after executing them.

My problem is that I can't figure out how to push a function into an array and then execute it. This is what I have so far:

var dialogQueue = []

dialogQueue.push(errorCall("test", "test", "test", "test"));

for (var queueNum = 1, 1 < dialogQueue.length, 1++) {
    alert(dialogQueue[1])
}

And if it helps, my code for showing the error messages:

function dialogShow() {
    $(".dialog-con").css("display", "block").css("background", "rgba(0,0,0,.8)")
    $(".body-wrapper").addClass("errorFilter");
    $(".dialog-anim").animate({
        opacity: 1,
        marginTop: "-=20px"
    })
    setTimeout(function () {
        $(".errorFilter").addClass("blur");
    }, 100);

}

function dialogHide() {
    $(".dialog-con").css("background", "rgba(0,0,0,.0")
    $(".body-wrapper").removeClass("blur");
    $(".dialog-anim").animate({
        opacity: 0,
        marginTop: "-=25px"
    }, 300)
    setTimeout(function () {
        $(".dialog-con").css("display", "none");
        $(".body-wrapper").removeClass("errorFilter");

        // Code for removing the function from the array after pushing OK on the dialog

    }, 1000);
}

function errorCall(title, sub, text, code) {
    $(".dialog .title").text(title);
    $(".dialog .subtitle").text(sub);
    $(".dialog .text").html(text);
    $(".dialog .error-code").html(code);
    dialogShow();
}

I'll give you a fiddle with the full errorCall() function in action:

function dialogShow() {
    $(".dialog-con").css("display", "block").css("background", "rgba(0,0,0,.8)")
    $(".body-wrapper").addClass("errorFilter");
    $(".dialog-anim").animate({
        opacity: 1,
        marginTop: "-=20px"
    })
    setTimeout(function () {
        $(".errorFilter").addClass("blur");
    }, 100);

}

function dialogHide() {
    $(".dialog-con").css("background", "rgba(0,0,0,.0")
    $(".body-wrapper").removeClass("blur");
    $(".dialog-anim").animate({
        opacity: 0,
        marginTop: "-=25px"
    }, 300)
    setTimeout(function () {
        $(".dialog-con").css("display", "none");
        $(".body-wrapper").removeClass("errorFilter");
    }, 1000);
}

function errorCall(title, sub, text, code) {
    $(".dialog .title").text(title);
    $(".dialog .subtitle").text(sub);
    $(".dialog .text").html(text);
    $(".dialog .error-code").html(code);
    dialogShow();
}

errorCall("Hello stackoverflow!","This is how my error message dialog looks!","Blah blah blah blah","Code code code");
.dialog-con {
    height: 100%;
    display: none;
    position: fixed;
    width: 100%;
    background-color: rgba(0, 0, 0, .0);
    z-index: 50;
    transition: ease 300ms;
}

.dialog-anim {
    width: 100%;
    height: 100%;
    display: none;
    display: flex;
    flex-direction: column;
    justify-content: center;
    opacity: 0;
    margin-top: -20px;
}

.dialog {
    margin: auto;
    padding: 12px 27px;
    background: white;
    border-radius: 3px;
    width: 520px;
    transform: translateY(30px)
}

.dialog .title-con {
    margin-bottom: 25px;
}

.dialog .title {
    font-size: 35px;
    padding-bottom: 7px;
}

.dialog .error-code {
    margin-top: 15px;
    color: rgba(0, 0, 0, .6);
    font-family: "Courier New", Courier, monospace
}

.dialog .subtitle {
    font-size: 17px;
    color: rgba(0, 0, 0, 0.4);
}

.dialog .text {}

.dialog .button-con {
    margin-top: 25px;
}

.dialog button {
    margin: auto;
    float: right;
    color: white;
    border: none;
    padding: 9px 37px;
    background: #10b5ff;
    text-transform: uppercase;
    font-weight: bold;
    border-radius: 3px;
}

.dialog button:hover {
    background: black;
    cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="dialog-con">
        <div class="dialog-anim">
            <div class="dialog">
                <div class="title-con">
                    <div class="title">Error Message Title</div>
                    <div class="subtitle"></div>
                </div>
                <div class="text-con">
                    <div class="text">Error Message</div>
                    <div class="error-code"></div>
                </div>
                <div class="button-con" onclick="dialogHide()">
                    <button>Ok</button>
                </div>
            </div>
        </div>
    </div>

(The ok button displacement is a result of the tiny viewport, ignore it.)

So the reason I want to do this is that in the event that something triggers multiple errors, they get pushed to the array and shown one after one (Pressing OK shows the next one etc).

like image 745
Sebastian Olsen Avatar asked Sep 12 '26 02:09

Sebastian Olsen


2 Answers

You need to create a function wrapper to store them in the array. As it stands you're invoking errorCall as you push it to the array. Try this code instead:

var dialogQueue = []

dialogQueue.push(
    function () {
        errorCall("test", "test", "test", "test")
    }
);

for (var queueNum = 0, 1 < dialogQueue.length, queueNum++) {
    alert( dialogQueue[queueNum]() );
}

You also wanted to remove after execution, so could do it like this instead:

while(dialogQueue.length > 0) {
    alert( dialogueQueue[0]() );
    dialogueQueue.shift();
}

Here's a simplified example:

var funcArr = [];

funcArr.push( console.log("Cat") );
// This immediately calls console.log, logging "cat".  After console.log is
// evaluated we push its return value `undefined`

// Instead, we wrap the console.log in an anonymous function.  This gives us
// a function which will execute what we desire when it is called.
funcArr.push( function() { console.log("cat"); } );

// there is nothing to invoke now, because we are creating a new function.
// now if we:
console.log( funcArr );
// we get: [function anonymous()]

// So if we say:
funcArr[0];
// this will evaluate to:
function() {
    console.log("cat");
};

// Therefore invoking funcArr[0] calls an anonymous function, which runs
// the function we actually wanted to run.
funArr[0]();
like image 70
ChadF Avatar answered Sep 13 '26 15:09

ChadF


An alternative to ChadF's approach would be to instantiate a function and call a method on it when you want to show the message.

// Your base function
function error(a, b, c, d) { 
  this.show = function() {
    alert(a + " " + b + " " + c + " " + d);
  };
}

var dialogQueue = [];

// Creating an instance of "error"
dialogQueue.push(new error("test", "test2", "test3", "test4")); 
dialogQueue.push(new error("testing again", "test2", "test3", "test4")); 

alert("Data finished pushing");

for (var i = 0; i < dialogQueue.length; i++) {
    // Calling the "show" method from "error"
    dialogQueue[i].show();
}
like image 20
Jan Avatar answered Sep 13 '26 16:09

Jan