简体   繁体   中英

Preventing a function from calling until variable is defined in javascript/node.js

I'm guessing I'm doing this the wrong way and should be using promises or something but I'm trying to create a CMS whereby you can edit a mongodb document which then translates into a blog post or any template with the variables filled out.

My CMS creates a list of blogs which only have the blog image, author, title, date modified, and the mongodb document _id as a data-id attribute.

When you click on 1 of the blogs it passes the blogId via socket.io to the server, the server searches for the blog, then renders the blogTemplateForm.pug file and sends that html back to the client where the client checks if there's already html in the #editor container, deletes the html and then appends the new html inside the edit container where the user can then edit it.

Now this document lookup is handled by a mongoose model, then I set res.blog to the blog returned by that lookup via the callback function, I generate some forms for use at a later date but otherwise we then use that res.blog object to generate the html we want from the blogTemplate, and then send that html to the client.

This works great but for some unknown reason the res.blog object is sometimes undefined, even when it really shouldn't be, ie. in the next function.. like what? And so the app.render() will return an error and null for the html, so I made a loop to check whether blog is defined before rendering the template. But even this doesn't work as html sometimes gets passed as null... What gives?!

Failure

Success

If you have a look at my loop checking whether res.blog is defined it really makes no sense that any undefined res.blog object is making its way through.

socket.on('edit blog', function(blogId){
        var res = {};
        Blog.findById(blogId, function(err, blog){
            res.blog = blog
            res.form = Form(blog)
        }).then(function(){
            res.filledForm = Bridge(res.blog, res.form).getForm()
            delete res.form
            if (res.blog !== (undefined & null)) {
                app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
                    console.log(err);
                    console.log(html);
                    socket.emit('blog form', html)
                })
            } else while (res.blog == (undefined | null)) {
                if (res.blog !== (undefined & null)) {
                    app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
                        console.log(err);
                        console.log(html);
                        socket.emit('blog form', html)
                    })
                }
            }
        })
    })

I've tried using different operands but to no avail, always returns null about 5% of the time

if (res.blog !== (undefined | null)) {
    app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
        console.log(err);
        console.log(html);
        socket.emit('blog form', html)
    })
} else while (res.blog == (undefined | null)) {
    if (res.blog !== (undefined | null)) {
        app.render(blogTemplateFormPath,{blog: res.blog}, function(err, html){
            console.log(err);
            console.log(html);
            socket.emit('blog form', html)
        })
    }
}

Thank you for any help. The screenshots are high res 1080p x 2 so I think you'll be able to see the code.

because res.blog !== (undefined | null) is not doing what you think it is doing.

console.log( (undefined | null) ) // 0

There is no shortcut, you need to check each one.

if (res.blog !== undefined && res.blog !==  null)

or do a falsely check

if (!res.blog)

This looks fishy:

    Blog.findById(blogId, function(err, blog){
        res.blog = blog
        res.form = Form(blog)
    }).then(function(){
        ...
    });

You're passing a callback to findById() and are also treating it as a promise. I can imagine that this may cause all sorts of unexpected issues.

So use just one method. My suggestion would be to use the promise:

Blog.findById(blogId).then(function(blog) {
  if (! blog) {
    ...handle "blogId not found" here...
    return;
  }
  ...
}).catch(function(err) {
  ...handle errors here...
});

This will remove the need for res as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM