sonlexqt
sonlexqt

Reputation: 6469

MeteorJS - Why is my page doesn't re-render when the data changed?

I'm populating an app using MeteorJS 1.0.2.1. At first, this is my searchResults template:

<template name="searchResults">
    <div class="dummy-column">
        <h2>Search Results</h2>
        <ul>
            {{#each results}}
                <li>
                    {{city}} - {{state}}
                </li>
            {{/each}}
        </ul>
    </div>
</template>

And this is the script file that handle some events and provide the helpers for the searchResults template:

Template.searchResults.helpers({
    results: function(){
        console.log("reach here only 1 time !");
        Meteor.subscribe('zips_results', key, function(){
            return Zips.find().fetch();
        });
    }
});

var key = '';

Zips = new Meteor.Collection('zips');

$(document).ready(function() {
    $('.morphsearch-input').keyup(function(){
        key = $(".morphsearch-input").val();
    });
});

So what I want is that every time I type in the $('.morphsearch-input') search input, my app will return the respectively search result by calling this:

Meteor.subscribe('zips_results', key, function(){
                return Zips.find().fetch(); // And I've tested that this runs correctly
            });

But the problem is that it seems like the Template.searchResults.helpers.results only get called once (at the begin of the loading), which makes my template not changed. I still don't know why this doesn't work. So I hope that you guys can help me with this ! Thanks you guys so much in advanced !

Upvotes: 0

Views: 150

Answers (2)

mstamos
mstamos

Reputation: 111

First add to your searchResults Template the search input text template. It has to be in seperate template, read here why.

searchResults.js

<template name="searchResults">
{{>searchInput}}
<div class="dummy-column">
    <h2>Search Results</h2>
    <ul>
        {{#each results}}
            <li>
                {{city}} - {{state}}
            </li>
        {{/each}}
    </ul>
</div>

Use Session to do your template more interactive. At the below template we get typed text and store it at a Sesion variable.

searchInput.js

Template.searchInput.events({
  'keyup input.search-zip': function (event, template) {
      event.preventDefault();
      Session.set('searchZip', event.currentTarget.value);
  }
});

The corresponding template must be:

searchInput.html

<template name="searchInput">
    <div class="form-group">
        <input type="text" class="form-control search-zip" placeholder="Search for zip...">
    </div>
</template>

After that put the above at searchResults javascript file. Change your subscribe (Meteor.subscribe("zips")) to bring all your zip code into miniMongo and then at results helper find the data which user searched.

searchResults.js

//This brings all zips into miniMongo and then into helper you 
//make the query while the user typing
Meteor.subscribe("zips");
Template.searchResults.helpers({
    results: function() {
        return Zips.find({youKey:Session.get('searchZip')})
    }
});

I hope i help you a bit

Upvotes: 1

Peppe L-G
Peppe L-G

Reputation: 8345

The readyCallback for subscriptions shouldn't return anything (nothing will happen with the return value). I would do something like this:

Template.searchResults.helpers({
    results: function(){
        return Zips.find();
    }
});

Template.searchResults.events({
    'keyup .morphsearch-input': function(event, template){
        if(template.handle){
            template.handle.stop()
        }
        var key = event.currentTarget.value
        template.handle = Meteor.subscribe('zips_results', key);
    }
});

Template.searchResults.destroyed = function()
    this.handle.stop()
};

Upvotes: 0

Related Questions