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

get reactive data. #21

Open
chasemb opened this issue May 11, 2015 · 22 comments · May be fixed by #54
Open

get reactive data. #21

chasemb opened this issue May 11, 2015 · 22 comments · May be fixed by #54

Comments

@chasemb
Copy link

chasemb commented May 11, 2015

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
Copy link

+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
Copy link

+1

@petermikitsh
Copy link

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
Copy link

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
Copy link

+1

Has anyone figured out any workaround for this?

@ZedZhang
Copy link

+1

@markshust
Copy link
Contributor

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

@markshust
Copy link
Contributor

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
Copy link
Contributor

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
Copy link
Contributor

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
Copy link

achirkof commented Dec 1, 2015

+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
Copy link

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

@pauljohncleary
Copy link

+1

1 similar comment
@urco
Copy link

urco commented Dec 24, 2015

+1

@ackzell
Copy link

ackzell commented Dec 27, 2015

"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
Copy link

urco commented Dec 29, 2015

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
Copy link

+1

@bompi88 bompi88 linked a pull request Jan 28, 2016 that will close this issue
@bompi88
Copy link

bompi88 commented Jan 28, 2016

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

@tonychenc
Copy link

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

@steinitz-zz
Copy link

@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
Copy link

bompi88 commented Mar 1, 2016

@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
Copy link

@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.

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

Successfully merging a pull request may close this issue.