meteorhacks / search-source

Reactive Data Source for Search
MIT License
145 stars 33 forks source link

get reactive data. #21

Open chasemb opened 9 years ago

chasemb commented 9 years ago

Package does not return reactive data. I've forked your example app, searched for a particular package, edited the 'packageName' in mongo. The data in the app will not update until I re-query the search.

Please advise.

SarahTan commented 9 years ago

+1 to this issue.

The readme says "You can get the reactive data source with the PackageSearch.getData api" but when I use that, the data on the client side doesn't automatically reflect my updated documents.

kyooriouskoala commented 9 years ago

+1

petermikitsh commented 9 years ago

I'm getting reactive data with this package. Make sure your event handler is properly configured so your search works. For me, it was as simple as changing change input to keyup input.

JulianKingman commented 9 years ago

I'm having the same issue, it's not updating when it's changed. If I search for the document, it shows me the updated name, however if I press escape or backspace, it shows me the name it used to be.

lauriiii commented 9 years ago

+1

Has anyone figured out any workaround for this?

ZedZhang commented 9 years ago

+1

markshust commented 9 years ago

same solution as @petermikitsh. once changed from onChange to onKeyUp, all is reactive now. this is a non-issue.

markshust commented 9 years ago

i had fun getting this to work in react. while it was very simple, it was tough to figure out as im still new to reactive programming. hope this helps someone:

  getInitialState() {
    return {
      name: "",
      items: []
    };
  },
  handleChange(e) {
    var name = e.target.value;

    this.setState({name: name});

    if (name.length >=3) ItemSearch.search(name);
  },
  handleKeyUp() {
    this.setState({items: ItemSearch.getData()});
  },
markshust commented 9 years ago

ok -- this seems to only work locally, but not with any latency involved. actually, if you watch state and add a record to the database, getData is NOT reactive. perhaps this can help simulate the root of the issue.

markshust commented 9 years ago

This is in fact a non-issue. I was not setup to listen to reactive data sources in React. Here is the correct config if anyone wants to see it:

...
  mixins: [ReactMeteorData],
  getMeteorData() {
    return {
      items: ItemSearch.getData()
    };
  },
  getInitialState() {
    return {
      name: ""
    }
  },
  handleChange(e) {
    var name = e.target.value;

    if (name.length >= 3) ItemSearch.search(name);

    this.setState({name: name});
  },
...

Then you listen to this.data.items instead of this.state.items.

achirkof commented 8 years ago

+1 Data not really reactive or I use this package wrong. I have a search result after page loaded and if add item in database it will not appear on the page. If use search field and type item name - it appear on the page. For trigger search active I use keyup event. Below are parts of my code. template.js

Template.tpl.onRendered(function() {
    ExercisesSearch.search(' ');
});

Template.tpl.events({
    'keyup #searchExercises': _.throttle(function(event) { 
         var text = $(event.target).val().trim();
         ExercisesSearch.search(text);
     }, 200)
});

search.js server

SearchSource.defineSource('exercises', function(searchText, options) {
     //var options = {sort: {isoScore: -1}, limit: 20};

     if(searchText) {
         var regExp = buildRegExp(searchText);
         //var selector = {exerciseName: regExp, createdBy: Meteor.userId(), isDeleted: false};
         var selector = {
             exerciseName: regExp,
             $or: [{
                 createdBy: Meteor.userId(),
                 isPrivate: true
             }, {
                 isPrivate: false
             }],
             $and: [{
                  isDeleted: false
             }]};     
             return Exercises.find(selector, {sort: {isoScore: -1}, limit: 20}).fetch();
     } else {
         return Exercises.find({
             $or: [{  
                 createdBy: Meteor.userId(),
                 isPrivate: true
             }, {
                 isPrivate: false
             }],
             $and: [{
                 isDeleted: false
             }]
         }).fetch();
     }
 });

search.js client

var options = {   
     keepHistory: 1000 * 60 * 5,
     localSearch: true
 };                
 var exerciseFields = ['exerciseName'];
 ExercisesSearch = new SearchSource('exercises', exerciseFields, options);

page.html

<div class="row">
    <div class="col-lg-12">
        <div class="hpanel">
            <div class="panel-body">
                <div class="input-group">
                    <input class="form-control" id="searchExercises" type="text" placeholder="Search..">
                </div>
            </div>
        </div>
    </div>
</div>

...

{{#each exercisesList}}
    <div class="row">
        <div class="col-sm-12">
            <div class="hpanel filter-item">
                <div class="panel-body" name="exercise" id="{{_id}}">
                    <a href="{{pathFor 'exercise'}}"><h4 class="m-b-xs">{{exerciseName}}</h4></a>
                    <div class="container-fluid">
                        <p class="small">{{{substrVar exerciseDesc "500"}}}</p>
                    </div><br>
                </div>
            </div>
        </div>
    </div>
{{/each}}

tpl_helper.js

Template.tpl.helpers({
exercisesList: function() {
         return ExercisesSearch.getData({                    
             transform: function(matchText, regExp) {    
                 return matchText;                   
             },
             sort: {isoScore: -1}                    
         });
     }
});

I can repeat search query in browser console and "hidden" on the page item present in result.

justjoolz commented 8 years ago

Having the same issue here also, updating values on an entry to the db are not reactively rendered

pauljohncleary commented 8 years ago

+1

urco commented 8 years ago

+1

ackzell commented 8 years ago

"Having the same issue here also, updating values on an entry to the db are not reactively rendered"

I am experiencing the same as you.

urco commented 8 years ago

Definitely is not a "real reactive" package. It only takes a "snapshot" from the results returned by the query... I hope in next update it will be solved because the package works great.

milosbarlov commented 8 years ago

+1

bompi88 commented 8 years ago

Tried to implement one approach to this problem. Take a look #54 .

tonychenc commented 8 years ago

@bompi88 well patch, but the performance is an issue +1

steinitz-zz commented 8 years ago

@bompi88 Thanks for sharing your patch. I like your idea. Also, your patch may clarify things for those contributing confusion by saying it's a "non-issue" etc.

Looking closely at your patch, it appears to me that while it does react to changes to documents in the search results, it doesn't react to documents which may have been inserted (added), 'externally'. Can you please confirm that?

bompi88 commented 8 years ago

@steinitz That's true. If that should be supported, I think this package should be more module-based, mongodb and rest-based or something similar. Each module have separate implementation of the local store. I think this package tries to provide a way of searching dependent of which search engine you are using, and therefore the reactivity gets put on the sideline. Only mongodb searches would utilize this kind of reactivity, am I right?

steinitz-zz commented 8 years ago

@bompi88

Thanks for your thoughtful reply. You wrote:

If that should be supported, I think this package should be more module-based, mongodb and rest-based or something similar.

Maybe so. Rest-based might be a step backwards though.

I think this package tries to provide a way of searching dependent of which search engine you are using, and therefore the reactivity gets put on the sideline.

That might be true in theory, but, for example, getData() currently uses hard-coded Mongo selectors.

Only mongodb searches would utilize this kind of reactivity, am I right?

Good question. I'll be interested to see how Meteor handles reactivity with other databases.

In any case, your clever solution brings us closer to having a truly reactive fast search. I'd be interested to hear about any inspiration you might have about reacting to newly-created docs.

My only idea at present, a crude one, is a way to force SearchSource to 'start over' - MyCollectionSearchSource.reset(), maybe, which the app calls when it creates a new document. Ugh. You can see why I'm poking around for a real solution.

Thanks again for your thoughts and for sharing your work.