Git Product home page Git Product logo

algolia / algoliasearch-client-javascript Goto Github PK

View Code? Open in Web Editor NEW
1.3K 97.0 216.0 60.62 MB

⚡️ A fully-featured and blazing-fast JavaScript API client to interact with Algolia.

Home Page: https://www.algolia.com/doc/api-client/javascript/getting-started/

License: MIT License

HTML 0.08% JavaScript 5.41% Shell 0.11% TypeScript 94.32% Dockerfile 0.08%
algolia api-client javascript search

algoliasearch-client-javascript's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

algoliasearch-client-javascript's Issues

CommonJS/AMD/UMD compatibility

tl;dr;

var algoliasearch = require('algoliasearch');
var client = algoliasearch({
  applicationID: '',
  apiKey: ''
});

Boring stuff

Our current JavaScript client is not commonJS compatible.

It cannot be used with requireJS or browserify.

The only way to use our module is to copy paste the <script src=..> tag in a webpage and use the globally available AlgoliaSearch.

This type of JavaScript library usage pattern is old and we must provide modern module loaders compatibility.

TODO

  • module.exports = algoliasearch; (Why "algoliasearch"? see #40 )
  • algoliasearch.helper = require('./lib/helper');
  • for npm users: no build needed
  • for requirejs/amd/umd/standalone users: build with browserify standalone, browserify -s algoliasearch index.js
  • add dist/ to .npmignore
  • stop using grunt for build, browserify handles it all
  • remove browserify-shim from package.json, no more used

server/builds/node.js: malformed end response crashes app

Thank you for this cool search service/client!

My app's integration tests have been crashing quite a bit whenever deletion of a non-existant index occured. The crash happened because src/server/builds/node.js expects data as parseable JSON
which you can see from:

        // algoliasearch-client-js/src/server/builds/node.js#L135-140
        resolve({
          statusCode: res.statusCode,
          body: JSON.parse(Buffer.concat(chunks))
        });

but it actually received back response

<html>
<head><title>400 Bad Request</title></head>
<body bgcolor="white">
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>

Clone the cached hits?

Hey,

When we modify the content object to display it, we sometimes have a problem when content is sent from the cache, because it has already been modified before.
Would it be possible to deepclone this cached object before sending it?

Thanks!

Merge node and js version of algolia-client

In order to realise full blown hyper trendy isomorphic apps, we should be able to use the same library on both side of the internet (client and server). And from what I understand, it's not only an implementation problem, it is also an API problem. The signatures being slightly divergeant in one implementation or the other which prevents us from doing a drop in replacement of the lib on each side of the wire.

Plugins architecture

tl;dr;

There's no plugin infrastructure in the code, resulting in if (angular) if (jquery).

Create one that allows us to remove the specific builds code from the main algoliasearch.js.

TODO

  • create a plugin way to create specific jQuery and Angular builds rather than storing the custom code in the main algoliasearch.js file.
  • Remove specific builds code from main algoliasearch.js

Boring stuff

We have jQuery and Angular.js builds but the code needed by theses plugins is stored inside the main algoliasearch.js file.

This is not good because once we have 10 plugins we will be screwed and it complexifies the code a lot.

We must find a way to plug theses builds

We must have one entrypoint per plugin like today: src/algoliasearch.angular.js but it should store his own custom code.

remove the OPTIONS CORS call

f97236b commit reverted the setting of custom request headers because it didn't stop the OPTIONS request for CORS.

It mentions the request being POST still demands a OPTIONS request.

I found that if you set the Content-Type to: application/x-www-form-urlencoded and no custom headers you skip the OPTIONS request.

Try my version: http://directlyrics.com/algolia/ac.html

Remove console.log calls

Hi, how can I remove all console.log calls on the browser version (I'm using v3)? I couldn't find anything about this on the docs.
Thanks!

Method search shouldn't have query parameters split in two different arguments

in v2, the signature of this method is :
( query: String, cb: function || falsy, options: Object || falsy ) => Promise || ()

What I'd like to have is :
( params: Object || falsy, cb: function || falsy,) => Promise || ()

Motivation

The changes make the api on par with the REST api. This then simplify explanations about the fact you can have the query both in arguments and in the options. This also makes complex case, with parameters for the query more straightforward.

Cons

Other than breaking the API compatibility, it's less straightforward for simpler cases.

Set index method in the helper

Hi Team, I was implementing a browse solution and I noticed that could be a good idea on adding a method to set/change the index name in the helper.
Why? well, since we have to create different indexes for each "sort" option, we could just change the index name in the helper and then for example got to the page 0, that will let us to keep all the options, filters and also the callback method in the helper and refresh the same results in different order.
Thinking out loud, a sort method could be added to receive the index name, set the index and invoke to the "private" _search() method.

is there any reason about why don't have a function to change the index easily?

remove lodash-compat from main library

I first used lodash-compat as a way to use forEach, map, etc.. in ES3 environments.

In the end, it adds a looot of code for 3 function calls (~6kb gzipd). So let's use our own implementations our small unique modules.

  • remove lodash-compat functions by small modules/custom implementations

new AlgoliaSearch(appID, apiKey, opts, ..) => algoliasearch(params)

tl;dr;

var client = algoliasearch(applicationID, apiKey, {
  protocol: 'http', // force using https or http, previously named "method"
  hosts: [], // which hosts to use for all other requests but the first one
  tld: '', // which tld to use when computing default hosts
  timeout: 2000,
  jsonp: null // feature-detect/force/disable JSONP (null/true/false)
});

var helper = algoliasearch.helper(client, indexName, opts);

Boring stuff

The current constructor code has a lot of code going on and can be instanciated with a lot of different options/arity.

Also as it is a constructor, it must be used with new AlgoliaSearch().

I propose to have only one way to instanciate the client, use only named parameters and a factory function instead of a constructor.

This reduces the overhead while using our library.

Current signature is function(applicationID, apiKey, methodOrOptions, resolveDNS, hosts) and must be used with new AlgoliaSearch.

New signature will have only named parameters and will be used with algoliasearch(params).

TODO

  • remove the need of new AlgoliaSearch()
  • remove the need of new AlgoliaSearchHelper()
  • use only named parameters
  • drop resolveDNS. It's not used

References

How to get all the results

Hello, I read in the docs that:

query: (string) The instant-search query string, all words of the query are interpreted as prefixes (for example "John Mc" will match "John Mccamey" and "Johnathan Mccamey"). _If no query parameter is set, retrieves all objects_

However, when I search like this:

index.search(undefined, searchCallback, {facets: '*', page: pageNum});

It will search for the literal word 'undefined'. Same for 'null'.

Digging a bit on the code, I found that algoliasearch.js, line ~1206, does:

var params = 'query=' + encodeURIComponent(query);

(please mind I'm using v2.9.1).

Now, I didn't go to the spec, but it seems that encodeURIComponent(undefined) returns the string 'undefined', at least in the latest Chrome. This results in searching my Algolia index for that word, instead of retrieving all the results, as I intended to.

Is there a special syntax for retrieving all the results or is it a bug?

Merge Node.js/io.js and browser JavaScript clients

tl;dr;

We currently have two JavaScript-like clients:

Merge them in only one client: algoliasearch.

Boring stuff

We can have isomorphic JavaScript! Let's use the same JavaScript client on both Node.js and the browser.

As the request strategies are a little bit different between Node.js (keepalive using node-modules/agentkeepalive) and the browser (fallback to JSONP, non relevant for Node.js), there will be some code differences.

Luckily, using browserify we are able to swap out requires when in the browser.

TODO

First steps

  • Create V21 branch in the Node.JS client, patches will be done in this branch
  • first prototype exposing AlgoliaSearch JavaScript client in Node.JS
  • make testing stack handles the Node.JS client

Behavior

  • All indexing requests must use a timeout of 15 times the requestTimeout given (so 2s search timeout, 30s indexing timeout)
  • Set default timeout to 3s. Timeout is an inactivity timeout as per Node.JS request.setTimeout
  • All indexing requests must not use the dsnHost in both browser and node
  • Ensure headers must not be mutable between two requests calls (add a test)
  • Keepalive should be activated by default, it will not be possible to give another agent for now. It's not a requested feature, it should just works™
  • send x-user-agent as part of the url containing "Algolia for Node.JS/io.jsNode.js $NODEJSVERSION $MODULEVERSION" in both browser and node
  • let the user use only http if he wants to
  • remove any reference to document/window in AlgoliaSearch.js
  • provide a .destroy method in nodejs that will destroy the http Agent (and exiting the process)
  • implement custom headers: _addHeadersRateLimit, _addHeadersSecuredAPIKey

Methods

  • Implement some Node.JS client methods not implemented in the JavaScript client
    • index.getObjects
    • index.deleteObjects
    • index.deleteByQuery
  • Implement and rework some methods
    • rename client.setTimeout in client.setRequestTimeout
    • client.multipleQueries
      • Deprecate client.startQueriesBatch, client.addQueryInBatch, client.sendQueriesBatch (already implemented in JS V3)
    • client|index.addUserKey, client|index.addUserKeyWithValidity, client|index.addUserKeyWithValidityAndIndexes, client|index.updateUserKey, client|index.updateUserKeyWithValidity, client|index.updateUserKeyWithValidityAndIndexes => can be solve by only client|index.addUserKey (POST) and client|index.updateUserKey (PUT)
      • deprecate client|index.addUserKeyWithValidity (already implemented in JS V3)
      • remove client|index.addUserKeyWithValidityAndIndexes, client|index.updateUserKey, client|index.updateUserKeyWithValidity, client|index.updateUserKeyWithValidityAndIndexes (not implemented in JS V3)
  • Implement only for node some functions that cannot be ported to browsers:
    • generateSecuredApiKey, it uses crypto functions, too heavy for browser
    • allow passing functions to be attached to the prototype for non portable browser functions like
    • create default empty functions throwing when not implemented in the browser with a clear message
    • remove ClassToDerive feature, must be done by the user
    • disable cache in the Node.JS client on search and multiple queries, add params to createAlgoliaSearch
    • client.useSecuredAPIKey, client.disableSecuredAPIKey
    • client.enableRateLimitForward, client.disableRateLimitForward

Parse build (src/server/builds/parse)

  • requirable via require('algoliasearch/Parse'), but build in src/server/builds/parse.js
  • promise.delay will use nextTick()
  • Inherit from Node.JS client, but use AlgoliaSearch constructor
  • installable via wget/curl the main dist/file
  • build process using webpack (one big file to satisfy parse)
  • inherit from AlgoliaSearchServer, to share methods with the nodejs client

Testing

  • test on travis-ci for Node .10 .12 io.js
  • add specific node.js request strategy: error, timeouts
  • test our node.js client is using keep-alive

Examples

  • add node.js examples
  • add parse example

Misc

  • deprecate npm/algolia-search (multiple latest versions)
  • update https://github.com/algolia/algoliasearch-client-node readme to display a warning + goto algoliasearch
  • update website
    • clearly say that Node.JS and browser clients are the same and usable in both environments
    • clearly say that some methods are not usable in the browser ()
  • create Node.JS migration guide
  • warn clients wanting to use the isomorphic JS client
  • ttAdapter belongs only to the browser build
  • get interesting info from Node.JS readme and set it in JavaScript readme
  • use and provide a modern parse setup with parse-cli parse-require (impossible)
  • update website on parse

bug global.document undifined

Hi, I have two page. One is Okay but on the second page, I have this error :
Uncaught TypeError: Cannot read property 'location' of undefined
caused by :
var protocol = global.document.location.protocol;
inside this lib :
http://cdn.jsdelivr.net/algoliasearch/3/algoliasearch.js

"global" is not null
I don't understand why and I haven't found the solution. Only replace this line by :
var protocol = window.document.location.protocol;
and all is okay but it's not a good solution...

Named argument for js client.

This issue is not exactly an issue, but I thought it might be a good thing to raise the subject before the client gets very popular. Have you thought of using a dictionary as an argument for the creation of the Algolia object?

As a benefit,

  1. you could give the JSON representation of this dictionary in all the place where you present the user credentials. It will be a valid literal, ready for copy-paste for JS, NodeJS but also python !

  2. it will make it easier for you to grow the API options.

  3. it will help people, as their configuration will probably, be in one way or another, serialized or defined beforehands in their code.

algolia in Bower

It would be very nice to have Algolia js library on Bower, in our company we use Bower to handle js files and make the pertinent upgrades.

Thank you!

TypeError: string is not a function

I have a strange problem where my node.js app doesn't return any search results and gives the error [TypeError: string is not a function].

It is running on Heroku, and there are 3 environments (and 3 github branches). For some reason it all works fine on all but the master branch and live environment. I have merged a working branch with the master but still no luck. Running the master branch on my local machine with the same variables as the live Heroku site works fine too. Since the error does not say the line number or anything, I don't know how to investigate further. But since it just occurs when searching, I believe it's the Algolia API.

Any help appreciated.


Here is the code

exports.search = function ( req, res ) {

    getUser( req.token )
    .then( function ( user ) {

        index.search( req.query.terms, function( error, result ) {
            if ( error ) { 
                console.log( error )
                return res.status( 500 ).json( error.message )
            }

            return res.status( 200 ).json( result.hits )
        }, { facetFilters: [ 'user:' + user.id, 'stream:' + req.query.stream ], page: req.query.page, hitsPerPage: req.query.show } )

    })
    .catch( function ( error ) {
        console.log( error )
        return res.status( 500 ).json( error.message )
    })

}

ensure all methods accept a callback as last argument and only in last

tl;dr;

Example:
index.search signature is cryptic and embeds strange parameters like delay. It does not makes it clear that we must have a callback in last parameter.

Other signatures does not always have callback as last parameter.

TODO

  • remove delay parameter in .search(), should be implemented by the user if needed
    easily implemented with lodash.debounce for example
  • search can be called with (query, params) or (params)
  • check all method signatures are using a callback as last parameter
  • rework addUserKeyWithValidity signature

Merge JavaScript and Node.JS libraries

Are you interested in merging the client-side algoliasearch library along with
the server-side (Node.JS) library?

The goal would be to have one codebase and the browser side built with browserify.

Browserside should only embed search features like today.

I wonder if you already thought about it.

remove jsonp: parameter

The jsonp:null/true/false parameter was used to force/disable jsonp.

After speaking with @redox, we decided that we could get rid of it for V3.

The V3 has a good implementation of the retry strategy and will not retry hosts.length * CORS when they are blocked.

As soon as there's an error (network error, server error) we will always use the fallback.

remove algoliasearch.helper from main project

For V3 we can remove the algoliasearch helper from the main library.

The first step is to externalize it, make it work with V3, this is V1.
A second pass can be done by @bobylito to then enhance and refactor the helper
so that it answers our user needs efficiently.

  • create a new github project for the helper (algoliasearch-helper-js)
  • npm init, start at V1.0.0
  • algoliasearch-helper in npmjs
  • algoliasearchHelper in UMD build (browserify -s algoliasearchHelper)
  • maybe some simple tests reusing the same toolset than the JS client (tape, zuul, travis)
  • helper search function should follow algoliasearch API on callbacks and promises: we should be able to use a callback or a promise.
  • PR on V3 branch to remove algoliasearch helper
  • udpate V3 changelog stating it's a breaking change
  • add a Changelog to the helper module
  • publish module to npm
  • add owners: npm owner add vvo, npm owner add speedblue
  • add to CDNJS/jsDelivr
  • update examples in the algoliasearch-client-js to use jsdelivr algoliasearch-helper

dobby

Wrapper and namespace

It seems like the AlgoliaSearch object is the only public API and that
AlgoliaUtils_* are just internal functions.

If this is the case, algoliasearch might benefits from a (function() {...})() wrapper in order to avoid global namespace pollution.

In addition, AlgoliaUtils_stringifyParamValues does not actually seems to be called anywhere.

callback(success, res or err) => callback(err, res or undefined)

tl;dr;

var client = algoliasearch({
  applicationID: '',
  apiKey: ''
});

var index = client.initIndex('indexName');

index.search('YAW callback', function searchDone(err, res) {
  if (err) {
    // do something with err, it's an instance of `Error`
    return;
  }

  // everything is cool, use response
  console.log(res.hits);
})

Boring stuff

The current callback convention for our JavaScript client is index.search(callback) where callback will be called with callback(success, res or err).

A popular way to handle asynchronous JavaScript is to use the callback(err or null, data or undefined) convention.

Notable projects using or leveraging this callback convention:

In the days of "isomorphic JavaScript", we must stick with a well used convention to not fall into the "guys using fancy callback pattern" basket.

TODO

  • move callback convention to callback(err, res)
  • note breaking changes in the issue if any

References

Linked with algolia/algoliasearch-client-node#18.

Do not break any client latest/algoliasearch.min.js usage

tl;dr;

We need to make the V3 release as smooth as possible in all cases. Even when the user includes the auto-updated "latest" algoliasearch.js

Boring stuff

We advocated for some time to use http://cdn.jsdelivr.net/algoliasearch/latest/algoliasearch.js which means "Use the latest alogliasearch library which udpates automatically, YOLO".

We want our users to be up-to-date but using versions strings like V2.x V2.9x V3.x etc.. So the user is able to get patch updates and new features updates while being sure his website will always work.

For now we must make the V3 release backward compatible in some way.

TODO

  • detect the algolia script was included using the "latest" version string using jsdelivr (cdnjs does not have such feature)
  • document.write() v2. script (drawback: not very efficient, but temporary)
  • or make a compatibility layer that use the new client from the previous constructor (too complex)
  • in all cases console && console.warn && console.warn('Warning, you are using the latest/ version which is not recommended. See our upgrade guide..')
  • find all clients using latest/ version and advise them to use jsdelivr V3 and upgrade guide

Stop committing dist/ files

For all our JavaScript projects, we use http://www.jsdelivr.com/ as a great way to distribute our builds to clients.

One drawback is that we have to commit dist/ files to our github repository for them to be picked up by their bot.

As committing dist/ files can be tedious and error prone, we should be able to avoid it.

It seems that by combining https://github.com/jsdelivr/libgrabber#add-updatejson-schema and npm prepublish and gitignore we would be able to push our dist files to the npm repository only and then have jsdelivr pick them up from here.

What do you think @bobylito @pixelastic?

Typeahead attributeName to obj.value mapping

instead of setting the value of obj (obj.value) equal to the first match, would it make more sense to allow an argument in the constructor to explicitly the set the mapping between the propertyName and the object.value so that the order in which the object attributes are created in the index does not determine how the object.value <--> attributeName mapping is determined?

// Method used by Typeahead.js.
        get: function(query, processRemoteData, that, cb, suggestions) {
            self = this;
            this.search(query, function(success, content) {
                if (success) {
                  for (var i = 0; i < content.hits.length; ++i) {
                    // Add an attribute value with the first string
                    var obj = content.hits[i];
                    var found = false;
                    if (typeof obj.value === 'undefined') {
                      for (var propertyName in obj) {
                        if (!found && obj.hasOwnProperty(propertyName) && typeof obj[propertyName] === 'string') {
                          obj.value = obj[propertyName];
                          found = true;
                        }
                      }
                    }
                    suggestions.push(that._transformDatum(obj));
                  }
                  cb && cb(suggestions);
                }
              }, self.typeAheadArgs);
            return true;
        },

Return promises to every call

tl;dr;

index.search('smg')
  .then(function(res) {
    // console.log(res.hits);
  })
  .catch(function(err) {
    console.error(err);
  });

Boring stuff

Current JavaScript API client only sends promises when using Angular.JS or jQuery build.

We must return promises to every API command.

We won't use Q or then, we use the native promise API, this is not a taste choice, only more relevant.

TODO

IE9 intermittently fails to execute ajax request

Using js client v2 or v3, the search callback does not execute. I'm testing on IE9 via browserstack.com. Live search can be found at http://mytennislessons.com/search?q=Austin

I only have access to Firebug Lite in browserstack, but with that, I don't see any js exceptions. Any ideas?

Relevant snippet

index.search('',
    { aroundLatLng: coordinates, aroundRadius: 32187, getRankingInfo: 1,
      hitsPerPage: self.perPage
    },
    searchCallback
  );

  function searchCallback(err, content) {
    alert('searchCallback'); // not executed
  }

previously exported globals should throw in V3

the client initialization changed in V3 so previously exported globals should also throw:

  • new AlgoliaSearch
  • new AlgoliaSearchHelper
  • AlgoliaExplainResults()
  • tests

Add a precise message linking to the migration guide to V3 hosted on github

Host vs Url

The NodeJS version takes a list of hostname, while the JS client takes a list of URI.
The confirmation email returns a host. Maybe that would be nice to choose either way
or detect that http:// is missing and add it in JS.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.