javascriptmongodbmeteormeteoritedatabase

How to make a simple database query in Meteor


Every time I have a new idea for an application, I start with Meteor. And every time I end up using something else. And I think it comes down to me not knowing how to do a simple database query.

Here's a hypothetical example. I want to make an app where the user types something into a box, presses a button, and then an image of whatever they typed in shows up. It uses some image search api.

<template name="image">
    <input type="text" class="description"></input>
    <button class="showImage"></button>
    <img src="{{img}}"></img>
</template>

Seems simple enough so far. Now there isn't a way to send information to the client without putting it in a database first, as is my understanding. Let's assume we have some function addToDB that takes queries and enters the image information into the database.

Template.image.events({
    'click .showImage': function() {
        addToDB($('.description').val());
    }
});

Great! That's still not too bad. But now to send the data back to the client...

//server.js
Meteor.publish("image", function(query) {
    Images.find({q: query});
}

But wait. We can't just subscribe when the client loads, because we don't know the query yet. So maybe the event handler needs to be

Template.image.events({
    'click .showImage': function() {
        addToDB($('.description').val());
        Deps.autorun(function() {
        Meteor.subscribe("images", $('.description').val());
    });
    }
});

Okay, let's feed that into the template...

Template.image.img = function() {
    return Images.findOne().imgsrc;
}

Nope, that results in an error because when the template is first loaded, we haven't subscribed to Images yet. So we can update the template like so:

<template name="image">
    <input type="text" class="description"></input>
    <button class="showImage"></button>
    {{#each info}}
    <img src="{{info.img}}"></img>
    {{/each}}
</template>

And then change the template filling function to:

Template.image.info = function() {
    return Images.find({}, {limit: 1});
}

And voila!

I spent longer than I'm willing to admit stumbling through all of that this evening. If it was just plain old node, I could've used some simple jQuery.

But there are a million amazing features that Meteor has that I really want to take advantage of. So what I'm hoping is that someone can show me the way. What mistakes did I make in this process, and in the final result? What's the nicest, cleanest, simplest way to get this done within a meteor app.

This is so complicated, within a framework that makes so many other things so simple. So how can I just make a simple database query?


Solution

  • Consider looking at the meteor examples they provide. All of the examples have the functionality of taking user input, managing collections, and displaying collection queries to templates.

    Most of your code looks fine but you are asking several questions at once and starting from a perspective that makes it difficult to answer. Some general notes:

    One problem in the code above is that your publish is not returning the query results. I assume that is a typo.