Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"server side search" and "Async reactive data-source" demos don't work locally #81

Closed
xinranxiao opened this issue May 21, 2015 · 23 comments

Comments

@xinranxiao
Copy link

Hi, for some reason when I run the demo locally, the "server side search" and "async reactive data-source" demos don't work while all the other ones work. I was wondering if anyone knows why this might be happening?

  Template.demo.helpers({
    search = function(query, callback) {
      Meteor.call('search', query, {}, function(err, res) {
        if (err) {
          console.log(err);
          return;
        }
        callback(res.map(function(v){ return {value: v.name}; }));
      });
    }
  });

Specifically, the callback for the function(query, callback) is not being called for either example:

However, it works on MeteorPad: http://meteorpad.com/pad/xX6kEQeAj6bqN9FdE/Typeahead

Has anyone else run into this problem before?

@dpankros
Copy link
Contributor

I too am seeing an issue locally with server side search. If I have some data cached in an array and feed it to the callback, it works fine. If it comes from the server, it doesn't. It makes me wonder if it's a timing issue, but I can't confirm it.

Template.foo.helpers({
  server: function(q, cb) {
    Meteor.call('serverSearch', q, function(err, res) {
      if (err) {
        console.log('ERROR: ' + err);
        return;
      }

      cb( res.map(function(v) {
        return {value: v.name};
      }));
    });
  },
  local: function(q, cb) {
    //filter only the values that start with the query
    var regex = new RegExp("^" + q);
    cb(_.filter(local_array, function(o) {
      return regex.exec(o.value) !== null;
    }));
  }
})

My server calls are making outbound http requests to a separate server for info and returning the data. They can take 2-3 seconds to return to the callback in some cases. E.g.:
client <------> meteor server <---http----> another server

@xinranxiao
Copy link
Author

I've tried just wrapping the callback inside a setTimeout and it does not work... the weird part is it works when the same exact code is deployed on meteorpad -- while running it locally or on meteor (with meteor deploy) does not work.

@thinkcontext
Copy link

I'm having the same issue as @dpankros , it works for local data but not server data. I was able to determine that the callback function in the helper is getting called and has the correct data but no changes are being made to the DOM.

@dpankros
Copy link
Contributor

@thinkcontext I should have mentioned that. The server method gets called and returns the correct information to the client. I am confident the data is getting passed to the callback correctly but it never displays.

@thinkcontext
Copy link

I got it to work after downgrading

@dpankros
Copy link
Contributor

@thinkcontext Can you elaborate on what you downgraded and to what version? Thanks!

@thinkcontext
Copy link

meteor add sergeyt:typeahead@=0.10.5_14

@dpankros
Copy link
Contributor

@thinkcontext Thanks for looking into it. Downgrading this package to 10.5_14 worked for me too.

@sergeyt
Copy link
Owner

sergeyt commented May 31, 2015

This issue is related to update to latest typeahead.js to v0.11.1 (see #78). Now async data source functions must have three arguments (query, sync, async). I found in typeahead.js repository only this commit where the API was changed without relevant issue.

@mahmoudkm
Copy link

In reference to this issue, I am getting
TypeError: callback is not a function

Whenever I start typing in the search box, I am using the following helper function params:

    Template.products.helpers({
          productsSerial: function(query, sync, callback){

Using sergeyt:[email protected]_3 will try to downgrade, and re-test

@dpankros
Copy link
Contributor

I don't think downgrading will fix this. 11.1_3 is working fine for me. My helper looks like:

Template.foo.helpers({
typeaheadHelper: function(query, sync, callback) {
    Meteor.call('serverSearchMethod', query, function(err, res) {
      if (err) {
        console.log(err);
        return;
      }
      callback(res.map(function(v) { return {value: v.name}; }));
    });
  }
});

have you tried adding javascript console.log(JSON.stringify(callback)); as the first line of your productsSerial helper? What are you getting for that argument?

@mahmoudkm
Copy link

Downgraded to meteor add sergeyt:typeahead@=0.10.5_14 and still getting the following error. Below is my .events function, any thoughts what I might be doing wrong / missing here? Thanks

  TypeError: callback is not a function
      at Template.products.helpers. productsSerial (http://localhost:3000/client/views/products/products.js?74bf22400c6ab30d0d09e7cea47356225819e453:76:15)
      at BlazeProvider.helpers._.each.dict.(anonymous function) (http://localhost:3000/packages/meteorhacks_kadira-debug.js?ee5ca93234e8f5b94a8e5560eb5ea8b7fcbb9c4d:339:29)
      at dataset.local (http://localhost:3000/packages/sergeyt_typeahead.js?236bb9c024fd2af671d3250e79e1bc82b413824f:2194:13)
      at Object.addLocalToIndex (http://localhost:3000/packages/sergeyt_typeahead.js?236bb9c024fd2af671d3250e79e1bc82b413824f:709:52)
      at jQuery.Callbacks.fire (http://localhost:3000/packages/jquery.js?dd8bac56f8fd3666d433d2285ae01e52597cc51a:3176:30)
      at Object.jQuery.Callbacks.self.add [as done] (http://localhost:3000/packages/jquery.js?dd8bac56f8fd3666d433d2285ae01e52597cc51a:3222:7)
      at Bloodhound.initialize [as _initialize] (http://localhost:3000/packages/sergeyt_typeahead.js?236bb9c024fd2af671d3250e79e1bc82b413824f:705:35)
      at Bloodhound.initialize (http://localhost:3000/packages/sergeyt_typeahead.js?236bb9c024fd2af671d3250e79e1bc82b413824f:713:58)
      at make_bloodhound (http://localhost:3000/packages/sergeyt_typeahead.js?236bb9c024fd2af671d3250e79e1bc82b413824f:2212:10)
      at resolve_datasets (http://localhost:3000/packages/sergeyt_typeahead.js?236bb9c024fd2af671d3250e79e1bc82b413824f:2029:10)




      Template.home.helpers({
        productsSerial: function(query, callback){
                    var matches, output;
                    matches = [];

                    Products.find({ "serial.number": {$regex: ".*"+ query +".*", $options: 'i'} }, {fields: {issn: 1}}).map(function(productDoc){

                          productDoc.serial = productDoc.issn.filter(function(e){ 
                                  if(e.number.match(".*"+ query +".*") ){
                                    return true;
                                  }
                          });

                          for (var i = 0, l = productDoc.serial.length; i < l; i++) {
                              matches.push(productDoc.serial[i].number);
                          }

                    });

                    output = $.map(matches, function (string) { return { value: string }; });            
                    callback(output);    
        }
      });

@dpankros
Copy link
Contributor

Which line is 76? callback(output) ??

@mahmoudkm
Copy link

@dpankros Exactly, just tried console.log(JSON.stringify(callback)); returns undefined

@dpankros
Copy link
Contributor

@mahmoudkm Look at the productsSerial definition. You're missing sync between query and callback. E.g. you have:

function(query, callback)

but it should be

function(query, sync, callback)

@mahmoudkm
Copy link

@dpankros I've tested it with and without sync, through the latest and newest releases...same error.

@dpankros
Copy link
Contributor

@mahmoudkm Try removing kadira debug. kadirahq/meteor-debug#11 and #86.
I was suspicious when I saw the SECOND stack frame of your trace was in that package.

@mahmoudkm
Copy link

@dpankros ooh! Thanks a lot, this instantly solved the undefined param error problem, sincerely appreciate your help :)

On a minor note, unfortunately the moment the undefined param error were gone a new problem hatched, where the search box stopped showing the filtered results panel. This behavior happens only when I am using the function with params as shown below. Any thoughts what I could be missing here? Thanks again

A. This works smoothly yet it doesn't help me filter results as needed

      productsSerial: function(){            
        return Products.find().fetch().map(function(it){ return it.name; });
      }

B. This filter records as displayed in console.log but the filtered results panel is not shown under the search box

      Template.home.helpers({
        productsSerial: function(query, sync, callback){
                    var matches;
                    matches = [];

                    Products.find({ "serial.number": {$regex: ".*"+ query +".*", $options: 'i'} }, {fields: {issn: 1}}).map(function(productDoc){

                          productDoc.serial = productDoc.issn.filter(function(e){ 
                                  if(e.number.match(".*"+ query +".*") ){
                                    return true;
                                  }
                          });

                          for (var i = 0, l = productDoc.serial.length; i < l; i++) {
                              matches.push(productDoc.serial[i].number);
                          }

                    });

                    console.log(matches); //display records filtered correctly in console...

                    callback(matches);    
        }
      });

@dpankros
Copy link
Contributor

@mahmoudkm I'm not sure why you're not getting results displayed. I would try changing your code to return an object. So, I would try changing:

for (var i = 0, l = productDoc.serial.length; i < l; i++) {
  matches.push(productDoc.serial[i].number);
} 

to

for (var i = 0, l = productDoc.serial.length; i < l; i++) {
  matches.push({value: productDoc.serial[i].number});
} 

Do you know that productDoc.serial[i].number is a string? If not, just to be sure, convert it to one.

@mahmoudkm
Copy link

@dpankros Thanks, I've tried converting returned data to objects as mentioned in your previous reply but I still can't see the filtered list. I am also so confused why I am not getting results displayed, ironically if I am using the no param function with just return Products.find().fetch().map(function(it){ return it.name; }); it displays without any issues!

Note: Yes I am sure that productDoc.serial[i].number is a string.

@dpankros
Copy link
Contributor

@mahmoudkm Can you confirm that your helper gets called each time you type a letter/number? (It should.)
Have you tried using Products.find().fetch().map(function(it){ return it.name; }); in your helper function ?

@mahmoudkm
Copy link

@dpankros Thanks for your reply,

Can you confirm that your helper gets called each time you type a letter/number?
Yes, and I can also confirm that the results displayed in console perfectly represent a filtered list based on the characters entered in the text box

Have you tried using Products.find().fetch().map(function(it){ return it.name; }); in your helper function ?
Yes works just fine.

@mahmoudkm
Copy link

@dpankros I finally managed to get it working, by moving the productsSerial: function code to a server method then calling the callback function with the returned result :)

Thanks a lot for your help and time, appreciate it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants