facetFilters in autocomplete algolia - algolia

I m facing difficulties setting facetFilters for algolia-autocomplete. If i want to filter based on a few organizations like :
source: $.fn.autocomplete.sources.hits(index, { hitsPerPage: 5, facetFilters:[ ['organization_id:1', 'organization_id:10'], ['listing_status:Published' ]] })
It works perfectly fine.
Now I want to pick the values from a text box, it does not work. If the value of a text box is
<input type="hidden" id="marketplace_organization_ids" value="'organization_id:1', 'organization_id:10'">
source: $.fn.autocomplete.sources.hits(index, { hitsPerPage: 5, facetFilters:[ [$('#marketplace_organization_ids').val()], ['listing_status:Published' ]] }),
Tried using array also but no result:
var name = ["'organization_id:1'","'organization_id:10'"];
source: $.fn.autocomplete.sources.hits(index, { hitsPerPage: 5, facetFilters:[ [name.join(',')], ['listing_status:Published' ]] })
I have used the above with one organization like and t works fine:
source: $.fn.autocomplete.sources.hits(index, { hitsPerPage: 5, facetFilters:[ ['organization_id:'+$('#user_organization_id').val() , 'distributors.id:'+$('#user_organization_id').val()] ] }),
Appreciate any help.

It seems that you are passing an incorrect value in your facetFilters, due to not parsing the value extracted from your input.
source: $.fn.autocomplete.sources.hits(index, {
hitsPerPage: 5,
facetFilters:[
[$('#marketplace_organization_ids').val()],
['listing_status:Published']
]
})
evaluates to
source: $.fn.autocomplete.sources.hits(index, {
hitsPerPage: 5,
facetFilters:[
["'organization_id:1', 'organization_id:10'"],
['listing_status:Published']
]
})
According to the Algolia's documentation about facetFilters, you should instead provide an array of strings rather a string representation of an array, e.g.
source: $.fn.autocomplete.sources.hits(index, {
hitsPerPage: 5,
facetFilters:[
['organization_id:1', 'organization_id:10'], // no more double-quotes
['listing_status:Published']
]
})
You can do that by splitting your value before passing it to the array:
const organizationFilter = $('#marketplace_organization_ids').val()
.split(',') // split string into array
.map(filter => filter.trim()) // remove whitespaces
console.log(organizationFilter); // ['organization_id:1', 'organization_id:10']

Related

eslint indent rule indents decorated members

In order to enable indents for chained methods:
await PostModel
.findOne({
author: user.user,
_id: id,
})
.populate('tickets', 'title status');
I have added the following MemberExpression to my eslintrc, as per eslint docs
indent": ["error", "tab", { "MemberExpression": 1 }],
but now I am experiencing problem with decorators, which get indented although my preference is to have them aligned with the member.
#prop({ type: String, required: true })
password: string;
Is there a way to address those two cases without a conflict?
I got the same problem as you did, and found this comment help, give it a try?
{
rules: {
// ...
"indent": ["error", 2, { "ignoredNodes": ["PropertyDefinition"] }]
}
}
According to this issue, you can partially disable the indent rule for decorators:
indent: [
'error',
'tab',
{
MemberExpression: 1,
ignoredNodes: [
'FunctionExpression > .params[decorators.length > 0]',
'FunctionExpression > .params > :matches(Decorator, :not(:first-child))',
'ClassBody.body > PropertyDefinition[decorators.length > 0] > .key',
],
},
],
This works for me.
#bujhmt's answer actually solved my problem, however, I needed to make some changes to it.
Before:
export abstract class MyAbstractClass extends AnotherClass {
#Column()
name!: string;
^^^^--> Expected indentation of 8 spaces, found 4
#Column()
address!: string;
^^^^--> Expected indentation of 8 spaces, found 4
}
Then I changed my .eslintrc rule to this:
"indent": [
`error`,
4,
{
"ignoredNodes": [
`FunctionExpression > .params[decorators.length > 0]`,
`FunctionExpression > .params > :matches(Decorator, :not(:first-child))`,
`ClassBody.body > PropertyDefinition[decorators.length > 0] > .key`,
],
},
],
And the errors were gone.

Can't change the pagination 'next' and 'prev' labels to my language in grid.js

There is no such option as change the prev and next button label in the documentation, and when i try to use string replacement or change the button innerHTML via Javascript, it doesn't work, is there any way that I can safely change the label?
You can use the language config (added since v1.5.0) to customize this:
new Grid({
columns: ['Name', 'Email', 'Title'],
sort: true,
search: true,
pagination: {
limit: 5
},
data: Array(50).fill().map(x => [
faker.name.findName(),
faker.internet.email(),
faker.name.title(),
]),
language: {
'search': {
'placeholder': '🔍 Search...'
},
'pagination': {
'previous': '⬅️',
'next': '➡️',
'showing': '😃 Displaying'
}
}
});
Also see this example: https://gridjs.io/docs/examples/i18n/

Joi when sibling then add extra rules at root

I have a complex validation which changes depending on the a value in the JSON.
{ type: 'a', thing: 1, foo: 'abc' }
{ type: 'b', thing: 2, bar: 123 }
I want to validate that if the type is a, then use one set of siblings, if b then use another set of siblings
I would like to use the when switch, but cant work out how to do this at the root.
Joi.object({
type: Joi.string().valid('a','b').required(),
thing: Joi.number().required()
}).when('type', {
switch: [
{ is: 'a', then: Joi.object({ foo: Joi.string() }) },
{ is: 'b', then: Joi.object({ bar: Joi.number() }) },
],
otherwise: Joi.forbidden(),
});
However this gives the following error:
Error: Invalid reference exceeds the schema root: ref:type
This kinda makes sense as an error but I don't know how to restructure this to get it to apply the selector at the root.
Im using latest JOI (16.0.1)
This can be resolved by prefixing the key name passed to .when() with a ., to denote the key as being relative to the object being validated:
Joi.object({
type: Joi.string().valid('a','b').required(),
thing: Joi.number().required()
})
.when('.type', { /* <-- prefix with . */
switch : [
{ is: 'a', then: Joi.object({ foo: Joi.string() }) },
{ is: 'b', then: Joi.object({ bar: Joi.number() }) },]
})
Here's a working example - hope that helps :-)

remote autocomplete by typeahead works only on unique queries

I am having problem setting up typeahead with bloodhound on two fields - symbol and name. You can try live version on my DGI portfolio manager and autocomplete remote source here.
Typeahead sometimes works and sometimes it does not.
If I type symbols like "jnj", "mcd", "aapl" it works.
However, when I type string from name like "corporation" and "inc" that have around 3000 objects with this name, it does not work. I doubt it is because it is loading, since json file is served quickly(under 250ms on localhost).
Firstly, I thought symbols work correctly and names are ignored. But I do get proper typeahead for some names: "apple" and "homestreet" for instance.
I believe it only works if there are 1 or 2 results. But I don't understand, json file serves always max 5 results.
Here are my codes:
views.py for autocomplete url:
from haystack.query import SearchQuerySet
import json
def autocomplete(request):
if request.GET.get('q', '') == '':
array = []
else:
sqs = SearchQuerySet().models(Stock)
sqs_symbol = sqs.filter(symbol_auto=request.GET.get('q', ''))
sqs_name = sqs.filter(name_auto=request.GET.get('q', ''))
sqs_result = sqs_symbol | sqs_name
array = []
print sqs_result.count()
for result in sqs_result[:5]:
data = {"symbol": str(result.symbol),
"name": str(result.name),
"tokens": str(result.name).split()
}
array.insert(0, data)
print array
return HttpResponse(json.dumps(array), content_type='application/json')
I added print so I know when it does not work.
search_indexes.py file:
from haystack import indexes
from stocks.models import Stock
class StockIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True)
symbol = indexes.CharField(model_attr='symbol')
name = indexes.CharField(model_attr='name')
# We add this for autocomplete.
symbol_auto = indexes.EdgeNgramField(model_attr='symbol')
name_auto = indexes.EdgeNgramField(model_attr='name')
def get_model(self):
return Stock
def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.all()
And in my template html file:
<script type="text/javascript">
$(function(){
var stocks = new Bloodhound({
datumTokenizer: function (datum) {
return Bloodhound.tokenizers.whitespace(datum.tokens);
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
limit: 5,
remote: {
url: "/search/autocomplete/",
replace: function(url, query) {
return url + "?q=" + query;
},
filter: function(stocks) {
return $.map(stocks, function(data) {
return {
tokens: data.tokens,
symbol: data.symbol,
name: data.name
}
});
}
}
});
stocks.initialize();
$('.typeahead').typeahead(null, {
name: 'stocks',
displayKey: 'name',
minLength: 1, // send AJAX request only after user type in at least X characters
source: stocks.ttAdapter(),
templates: {
suggestion: function(data){
return '<p>' + data.name + ' (<strong>' + data.symbol + '</strong>)</p>';
}
}
}).on('typeahead:selected', function (obj, stock) {
window.location.href = "/stocks/detail/" + stock.symbol;
});
});
</script>
EDIT: Some Examples
Json response:
[{"tokens": ["Johnson", "&", "Johnson"], "symbol": "JNJ", "name": "Johnson & Johnson"}]
Not working for "sto":
json response:
[{"tokens": ["QKL", "Stores,", "Inc."], "symbol": "QKLS", "name": "QKL Stores, Inc."}, {"tokens": ["SPDR", "DJ", "STOXX", "50"], "symbol": "FEU", "name": "SPDR DJ STOXX 50 "}, {"tokens": ["Statoil", "ASA"], "symbol": "STO", "name": "Statoil ASA"}, {"tokens": ["STORE", "Capital", "Corporation"], "symbol": "STOR", "name": "STORE Capital Corporation"}, {"tokens": ["StoneMor", "Partners", "L.P."], "symbol": "STON", "name": "StoneMor Partners L.P."}]
It is typeahead.js's bug. It should be fixed in version 0.11.2.

MongoDB - "The dollar ($) prefixed field \'$$hashKey\' in \'fieldName".$$hashKey\' is not valid for storage.'"

While trying to update a document I'm getting the above error for the field timesToDisplay.
MongoDB version 2.6.7.
The whole model:
msg = {
'name': '',
'template': '',
'displayDurInMilliSec': 0,
'timesToDisplay': [],
'images': [],
'texts': [],
'screen': []
}
I guess I will be getting the same error with the other 3 array fields.
I've tried using $set but sill getting the same error.
The code:
function updateMessage(msg) {
var conditions = {_id: msg._id}
, update = { 'name': msg.name,
'template': msg.template,
'displayDurInMilliSec': msg.displayDurInMilliSec,
'timesToDisplay': msg.timesToDisplay,
'images': msg.images,
'texts': msg.texts,
'screen': msg.screen
}
messageModel.update(conditions, update, callback);
function callback(err, numAffected) {
if (!err) console.log(numAffected)
else console.log(err)
}
}
EDIT: The msg parameter is a document in itself:
{ _id: '557d58abd54955480db6694f',
name: 'msg99',
timesToDisplay: [ { startDate: '2015-06-19T21:00:00.000Z',
'$$hashKey': 'object:214',
endDate: '2015-06-25T21:00:00.000Z',
daysOfTheWeek: [Object],
startTimeOfDay: '11',
endTimeOfDay: '13' } ],
images: [],
texts: [],
screen: [ 1 ],
'$$hashKey': 'object:54',
displayDurInMilliSec: '40189',
template: 'templates/Template2.html' }
The $$hashkey field is added by AngularJS when working with ngRepeat or ngOptions. In the case of ngRepeat you can change the repeat string by appending track by $index to it. For using ngOptions you'll have to filter out that field yourself. AngularJS provides a quick solution for filtering it out: angular.toJson. This will filter out all fields prefixed with two dollar signs. Check out the documentation.
I realize that this isn't a MongoDB answer, but this specific error ($$hashkey), is usually due to AngularJS.