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

Client side search? #3

Open
fardeem opened this issue Jan 12, 2015 · 19 comments
Open

Client side search? #3

fardeem opened this issue Jan 12, 2015 · 19 comments

Comments

@fardeem
Copy link

fardeem commented Jan 12, 2015

I have the data source on the client side. How can I use that?

@arunoda
Copy link
Member

arunoda commented Jan 12, 2015

That's not supported at the moment. But that's a good idea.
May be we should allow to define the data source in the client.
On Mon Jan 12 2015 at 4:06:48 PM Fardeem Munir notifications@github.com
wrote:

I have the data source on the client side. How can I use that?


Reply to this email directly or view it on GitHub
#3.

@fardeem
Copy link
Author

fardeem commented Jan 12, 2015

Yeah, make it available client side

On Mon, Jan 12, 2015 at 4:43 PM, Arunoda Susiripala <
notifications@github.com> wrote:

That's not supported at the moment. But that's a good idea.
May be we should allow to define the data source in the client.
On Mon Jan 12 2015 at 4:06:48 PM Fardeem Munir notifications@github.com
wrote:

I have the data source on the client side. How can I use that?


Reply to this email directly or view it on GitHub
#3.


Reply to this email directly or view it on GitHub
#3 (comment)
.

Fardeem Munir
www.erubai.com
@awesomerubai

@arunoda
Copy link
Member

arunoda commented Jan 30, 2015

I have add this feature.
See: https://github.com/meteorhacks/search-source#defining-data-source-in-the-client

Hope this is what you wanted

@shkomg
Copy link

shkomg commented Feb 16, 2015

Hi, Arunoda,

thank you for the awesome package. May you, please, provide working example for client search at https://github.com/meteorhacks-samples/meteor-instant-search-demo ?

Thank you.

@arunoda
Copy link
Member

arunoda commented Feb 16, 2015

Check here: http://instant-search-demo.meteor.com/

On Mon Feb 16 2015 at 2:56:48 PM shkomg notifications@github.com wrote:

Hi, Arunoda,

thank you for the awesome package. May you, please, provide working
example for client search at
https://github.com/meteorhacks-samples/meteor-instant-search-demo ?

Thank you.


Reply to this email directly or view it on GitHub
#3 (comment)
.

@shkomg
Copy link

shkomg commented Feb 16, 2015

Well, I can't find there anything defining data source in the client like .fetchData
May, you, pls, point me?

Thank you.

@arunoda
Copy link
Member

arunoda commented Feb 16, 2015

Ah nope. It's not there. I don't think I've a working example now.

On Mon Feb 16 2015 at 3:32:59 PM shkomg notifications@github.com wrote:

Well, I can't find there anything defining data source in the client like
.fetchData
May, you, pls, point me?

Thank you.


Reply to this email directly or view it on GitHub
#3 (comment)
.

@shkomg
Copy link

shkomg commented Feb 16, 2015

:( that 'd be awesome to have such an example.

may you, pls, point me quick on how I may use .fetchData? should it go before .getData?

As I do have reactive data source on client changing over some filters. So I need to adjust data source according to session var stage.

@Chos89
Copy link

Chos89 commented Mar 18, 2015

hey shkomg, did you manage to get .fetchData to work, any working examples?

@shkomg
Copy link

shkomg commented Mar 18, 2015

yep, I just 've written my own solution. That was quicker & simplier for my
case.

2015-03-18 19:43 GMT+02:00 Chos89 notifications@github.com:

hey shkomg, did you manage to get .fetchData to work, any working examples?


Reply to this email directly or view it on GitHub
#3 (comment)
.

Best regards

Serhiy Khvashchuk

@Chos89
Copy link

Chos89 commented Mar 18, 2015

Could you give any hints or code snippets on how did you do it?

@shkomg
Copy link

shkomg commented Mar 18, 2015

well, that's pretty simple:

I have 1st template with
<input type="text" id="search-box" placeholder="type search text here">

For the 1st template I have a keyup event on search box which creates
session with search text.

And for 2nd template I provide search results based on this session data.

Does it makes sense?

2015-03-18 20:24 GMT+02:00 Chos89 notifications@github.com:

Could you give any hints or code snippets on how did you do it?
You can email me on i.josip89@gmail.com if it's outside of scope of this
package...


Reply to this email directly or view it on GitHub
#3 (comment)
.

Best regards

Serhiy Khvashchuk

@Chos89
Copy link

Chos89 commented Mar 18, 2015

I think I understand what you are doing, but not sure if this would work in
my case, thanks anyway.

2015-03-18 19:50 GMT+01:00 shkomg notifications@github.com:

well, that's pretty simple:

I have 1st template with
<input type="text" id="search-box" placeholder="type search text here">

For the 1st template I have a keyup event on search box which creates
session with search text.

And for 2nd template I provide search results based on this session data.

Does it makes sense?

2015-03-18 20:24 GMT+02:00 Chos89 notifications@github.com:

Could you give any hints or code snippets on how did you do it?
You can email me on i.josip89@gmail.com if it's outside of scope of this
package...


Reply to this email directly or view it on GitHub
<
#3 (comment)

.

Best regards

Serhiy Khvashchuk


Reply to this email directly or view it on GitHub
#3 (comment)
.

@sbking
Copy link

sbking commented Apr 7, 2015

It would be nice if we could use this with a REST API data source on the client. The particular REST API I'm using has a rate limit per second per IP address, so it is not feasible to do the requests on the server.

@mattiLeBlanc
Copy link

Hi, I am current using the client side search too, getting my results from an external API and loading it in a subscription like this (client side):

 Meteor.call( 'getFeedContent', Session.get( 'feed' ).url, ( error, result ) ->
            if result
                instance.channel.set( result )

                handle = Meteor.subscribe( 'episodes', result.episodes )
                instance.autorun( ( c )->

                    # searchHandle = Meteor.subscribe( 'episodes', result.episodes )

                    if handle.ready()
                        console.log("eps", Episodes.find({}).count())
                        console.log("handle ready!")
                        EpisodesSearch.search( '' )
                        c.stop()
                )
            else
                console.error error
            instance.loading.set( false )

        )

On the server I have a publication named 'episodes' which get filled by the subscription and uses instance.added( 'episodes', Random.id() to populate the client collection.

Then finally I have a client side collection SearchSource declaration:

 if Meteor.isClient
    @Episodes = new Meteor.Collection( 'episodes' )
    options =
        keepHistory: 0
        localSearch: false

    fields = ['title']
    @EpisodesSearch = new SearchSource( 'episodes', fields, options )

    buildRegExp = ( searchText ) ->
        parts = searchText.trim().split(/[ \-\:]+/)
        return new RegExp("(" + parts.join('|') + ")", "ig")

    # set up client datasource
    EpisodesSearch.fetchData = (searchText, options, success) ->
        err         = null
        options     = {sort: { 'publishedDate': -1 }, limit: 20}
        if searchText
            # get rid of surrounding spaces
            searchText  = searchText.trim()
            selector    =
                title:  buildRegExp( searchText )
            console.log(selector)
            data = Episodes.find( selector, options ).fetch()
        else
            data = Episodes.find({}, options).fetch()
        # return result
        success(err, data)

Now I have the following weird issue, that when I do a search on one episode and then clear my search box again, the one episode episode result of the previous search is at the top of the new search result list.

I can do it all in my Chrome console. After page render, 20 episodes are loaded ordered by date desc. Then when I do EpisodesSearch.search('trash') it results one episode titled 'trash'. Then when I run EpisodesSearch.search('') it shows me 20 episodes, of which no 1 is Trash. Number 2 is the actual newest episode that was on top.
I am not using history and calling cleanHistory doesn't do anything.
Also when I do Episodes.find({}).fetch(), it still shows the original master list of episodes.
From this I deduce that SearchSearch has its own cache that is use not being refreshed.

Can anyone confirm this or tell me what I do wrong?

@Chos89
Copy link

Chos89 commented Apr 26, 2015

Check that your data doesnt have the same date
On Apr 26, 2015 12:30 PM, "mattiLeBlanc" notifications@github.com wrote:

Hi, I am current using the client side search too, getting my results from
an external API and loading it in a subscription like this (client side):

Meteor.call( 'getFeedContent', Session.get( 'feed' ).url, ( error, result ) ->
if result
instance.channel.set( result )

            handle = Meteor.subscribe( 'episodes', result.episodes )
            instance.autorun( ( c )->

                # searchHandle = Meteor.subscribe( 'episodes', result.episodes )

                if handle.ready()
                    console.log("eps", Episodes.find({}).count())
                    console.log("handle ready!")
                    EpisodesSearch.search( '' )
                    c.stop()
            )
        else
            console.error error
        instance.loading.set( false )

    )

On the server I have a publication named 'episodes' which get filled by
the subscription count and uses . instance.added( 'episodes', Random.id()
to populate the client collection.

The finally I have a client side collection SearchSource declaration:

if Meteor.isClient
@Episodes = new Meteor.Collection( 'episodes' )
options =
keepHistory: 0
localSearch: false

fields = ['title']
@EpisodesSearch = new SearchSource( 'episodes', fields, options )

buildRegExp = ( searchText ) ->
    parts = searchText.trim().split(/[ \-\:]+/)
    return new RegExp("(" + parts.join('|') + ")", "ig")

# set up client datasource
EpisodesSearch.fetchData = (searchText, options, success) ->
    err         = null
    options     = {sort: { 'publishedDate': -1 }, limit: 20}
    if searchText
        # get rid of surrounding spaces
        searchText  = searchText.trim()
        selector    =
            title:  buildRegExp( searchText )
        console.log(selector)
        data = Episodes.find( selector, options ).fetch()
    else
        data = Episodes.find({}, options).fetch()
    # return result
    success(err, data)

Now I have the following weird issue, that when I do a search on a one
episode and then clear my search box again the one episode of the previous
search is there at the top of the result list.

I can do it all in my Chrome console. After page render, 20 episodes are
loaded ordered by data desc. Then when I do EpisodesSearch.search('trash')
it results one episode titled trash. Then when I run
EpisodesSearch.search('') it shows me 20 episodes, of which no 1 is Trash.
Number 2 is the actual newest episode that was on top.
I am not using history and calling cleanHistory doesnt work.
Also when I do Episodes.find({}).fetch() is still shows the original
master list of episodes.
From this I deduce that SearchSearch has its on cache that is not cleared.

Can anyone confirm this or tell me what I do wrong?


Reply to this email directly or view it on GitHub
#3 (comment)
.

@mattiLeBlanc
Copy link

What do you mean with "Check if data doesn't have the same date".
Where can I find this 'date'? I am looking at the EpisodeSearch object but can't find any date.
As far as I know I am doing a new search so I don't understand why the previous result is being added on top.

@mattiLeBlanc
Copy link

I debugged the FetchData function just before the Success hits (cause there the data is correct),
and this is the function where the local storage is updated

SearchSource.prototype._updateStore = function(data) {
  var self = this;
  var storeIds = _.pluck(this.store.find().fetch(), "_id");
  var currentIds = [];
  data.forEach(function(item) {
    currentIds.push(item._id);
    self.store.update(item._id, item, {upsert: true});
  });

  var removedItem = _.difference(storeIds, currentIds);
  removedItem.forEach(function(id) {
    self.store.remove(id);
  });
};

The actual problem is that the episode Trash, is normally the 9 results in the first list of 20. When I search for Trash, it becomes the only result. When I clear the searchbox, Trash is the one result out of the 20 displayed, while it has an older publish date and should be in position 9.
So I guess, it is an ordering issue.

In the update store function:

  data.forEach(function(item) {
    currentIds.push(item._id);
    self.store.update(item._id, item, {upsert: true});
  });
  var removedItem = _.difference(storeIds, currentIds);
  removedItem.forEach(function(id) {
    self.store.remove(id);
  });

the removedItem array is empty because the storeIds will hold the 'Trash' entry and the currentIds will hold the 20 items (including the Trash entry), so nothing is removed.
So a couple of lines above where the upsert was executed, the Trash entry was already added in the previous search process, so when the 20 entries are stored I think the Trash entry is not added in on the 9th position because it was already there and will be before the new entries. That is why it is on position 1 instead of it's original position 9.

So I guess I know what is happening now, however I don't know how to proceed next.

Do I need to sort the result again in the Helper to get the right order? Seems a bit like a hack.
The real issue is the that FetchDate doesn't return the dataset according to the sort instructions that where provided.

Could this be fixed?

@mattiLeBlanc
Copy link

Adding the sort in the GetData fixes it for me:

episodes: ->
        instance = Template.instance()
        data = EpisodesSearch.getData(
            sort: {'publishedDate': -1}
            limit: 30
        )
        return data

so not sure if it was a bug or just me being silly.

One thing I found out that it is imperative that I stop the Autorun for the handle that subscribes the episode. If i don't do that it is really messing up the collection.

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

6 participants