Exclude Filters Using InstantSearch.js? - algolia

We are using Algolia to index content from a variety of sources and for a dozen different products. Right now I have one index and product is a configured facet.
I need to find a way to restrict searches to only those products the user owns.
I'm using the InstantSearch library and I've been reading through the documentation and various online forums for information on how to accomplish this.
Here is the code I'm trying to get working.
var client = algoliasearch("myAppId", "myApiKey")
var index = client.initIndex('myIndex');
var search = instantsearch({
appId: 'myAppId',
apiKey: 'myApiKey',
indexName: 'myIndex',
urlSync: {},
attributesToHighlight: 'full'
});
search.addWidget(
instantsearch.widgets.refinementList({
container: '#products',
attributeName: 'products',
operator: 'or',
limit: 100,
sortBy: ['name:asc'],
templates: {
}
})
);
search.addWidget({
init: function (options) {
options.helper.addFacetRefinement('products', 'Product A');
}
});
search.start();
But when I execute this I get an error stating "Uncaught Error: products is not defined in the facets attribute of the helper configuration".
What step am I missing? Or am I approaching this in the wrong way?
Any guidance appreciated.
~ Greg

I found an answer to my needs. I had to add a searchParameters option to the instantsearch configuration call. And I had to write some code to hide the unwanted products from my refinementlist widget.
First step is to create an array of the products I want to hide.
var productsToExclude = ['product-a','product-b'];
I had to pass this list of items to hide via the "searchParameters" instantsearch configuration option.
var search = instantsearch({
appId: 'myAppId',
apiKey: 'myApiKey',
indexName: 'myIndex',
urlSync: {},
attributesToHighlight: 'full',
searchParameters: { facetsExcludes: { "products": productsToExclude}}
});
And I also had to write a bit of code to hide the items in the refinementList widget.
var onRenderHandler = function () {
for (var p in productsToExclude) {
$("input[type=checkbox][value='" + productsToExclude[p] + "']").parent().hide();
}
};
search.on('render', onRenderHandler);

Related

Rally: Date User Story is Defined

I am writing a program that needs to fetch user stories that are defined before day 3 of a release. Is there a way to find out what day a user story was set to the 'defined' state so that I could query that?
I looked through the Web Service API docs but I couldn't find anything that could help me, although I could have missed something.
This is the code I am using to get the 3rd day of a release:
var releaseStart = combobox.getRecord().get('ReleaseStartDate');
releaseStart.setDate(releaseStart.getDate()+3);
this._startDate = Rally.util.DateTime.toIsoString(releaseStart);
But I'm not sure how to relate this to the date a user story is defined.
If anyone could help it would be much appreciated!
You're right- this piece of data does not exist in the standard WSAPI. You can get it from LookbackAPI however. How about something like this to get started?
var releaseStart = combobox.getRecord().get('ReleaseStartDate');
var startDate = Rally.util.DateTime.add(releaseStart, 'day', 3);
var snapshotStore = Ext.create('Rally.data.lookback.SnapshotStore', {
context: {
workspace: this.getContext().getWorkspaceRef()
},
find: {
_ProjectHierarchy: this.getContext().getProject().ObjectID,
_TypeHierarchy: 'HierarchicalRequirement',
ScheduleState: {$gte: 'Defined'},
__At: startDate
},
sort: {
_UnformattedID: 1
},
fetch: ['FormattedID', 'Name', 'ScheduleState'],
limit: Infinity,
autoLoad: true,
listeners: {
load: function(store, records) {
//TODO: work with records here
}
}
});
More information on working with the Lookback API is here: https://help.rallydev.com/apps/2.1/doc/#!/guide/lookback_api

How to show data from mongoDB with ObjectID

i have an "back end" application which write in MongoDb (in database i have _id: with ObjectId("13f6ea...002")) i use meteor app to show information. Everything was good i displays list of information with {{#each}}. But when i wanted show one element with '_Id' nothing works.
I read this issue and adapt my code to get right root, But i can't display anything on the page. I tried to write Template helpers but it didn't helped
Db record:
{
_id: ObjectId("13f6ea...002"),
url: "foo",
title: "bar",
published: "2014-08-22 03:26:21 UTC",
image: "foo.jpg",
summary: "foo ",
categories: [
"F",
"B"
],
...
}
Route:
this.route('news', {
path: '/news/:_id',
template: 'news',
waitOn: function () {
var id = this._id;
Meteor.subscribe('news', id);
},
data: function() {
var id = this.params._id;
return News.findOne({ _id: Meteor.Collection.ObjectID(this.params._id)});
},
action : function () {this.render();},
});
Publish
Meteor.publish('news', function(id) {
return News.find({_id: id});
});
Template which redirect to unique post
<h4>{{title}}</h4>
And template is just {{news}}
How can i fix this?
UPDATE
My solutions to fix that:
router.js
waitOn: function () {
var id = this._id;
Meteor.subscribe('News', id);
},
data: function() {
return News.findOne(new Meteor.Collection.ObjectID(this.params._id));
},
and in template
<a href="news/{{_id._str}}">
Navigate to the appropriate url in your browser (i.e. localhost:3000/news/[_id]), open the console and enter:
Router.current().data()
That will show you the data context of the current route. Either it returns nothing, in which case there is a fundamental problem with your News.findOne query as it's returning nothing, or (more likely) it returns the required document.
In the latter case, as far as I can see there is no news property within that document, which is why it isn't rendering anything. If you change {{news}} to {{url}} or {{summary}} I would imagine it would render the requested property.
If by {{news}} you're trying to render the entire document, then (aside from the fact that it will render as something like [Object]) you need to make news a property of the object returned by your data function:
return {
news: News.findOne({ _id: Meteor.Collection.ObjectID(this.params._id)});
};
Getting Document with _id :
In the .js file under events, Say on click event and Collection EventList :-
'Submit form' : function () {
var id = this._id;
return EventList.find({_id : id}).fetch();
}
This would return the object for the id. In my Case, I am displaying a field for all documents in Collection. User selects a record and clicks Submit, which fetches all Document fields and displays to the User

How to read a collection that depends on another one in Meteor

I'm trying to load the latest post from a collection and at the same time all of the comments of that same post. The collection have references instead of storing the whole documents inside each other:
Post { title, body, etc..}
Comment { postId, body, etc.. }
I'm using iron-router as the routing package and in the route of my page I'm subscribing with this way:
this.route('home', {
path: '/',
template: 'home',
waitOn: function () {
return [
Meteor.subscribe('latestPost'),
Meteor.subscribe('lastReadPost')
];
}
});
The code that retrieves the post is simply:
Posts.findOne({}, {sort:{createdAt:-1, limit:1}});
Now the problem is that I don't know how to retrieve the comments without reading the whole collection. I can't subscribe in the router as I still do not have the post ID to query the Comments collection.
I guessed I could do that from the Template, but of course if I query the Comments collection, it's still empty. But I do have the postId as it's inside the Posts collection at that time. But I would need to trigger a subscription from the Template and that doesn't sound like a clean solution.
What would the best practice be? Thanks!
Server side code:
Meteor.publish("latestPost", function () {
var post = Posts.find({}, {sort:{created:-1}}).fetch()[0];
console.log("publish : " + post.title);
return [
Posts.find({_id: post._id}),
Comments.find({postId: post._id})
];
});
Client side code:
this.route('home', {
path: '/',
template: 'home',
waitOn: function () {
return [
Meteor.subscribe('latestPost')
];
},
data:function(){
return {
post:Posts.findOne(),
comments:Comments.find()
};
}
});
Check this repository to see whole example.
After user changes to another route, then subcriptions are being automatically stopped.
I would also include a limit in the server side finder options
{sort : {created : -1}, limit : 1}

backbone.js won't fetch data and populate the collection

I have this setup: require.js + backbone.js, that which populate the collection using fetch function of backbone
orders.js(collection)
define([
'underscore',
'backbone',
'models/item'
], function(_, Backbone, Item){
var Orders = Backbone.Collection.extend({
model: Item,
url: 'json/items',
initialize: function(){
},
});
return orders = new Orders();
});
orders.js(views)
define([
'jquery',
'underscore',
'backbone',
'collections/orders',
'models/item',
'text!templates/orders.tpl',
], function($, _, Backbone, Orders, Item, ordersTemplate){
var OrdersView = Backbone.View.extend({
model: Orders,
template: _.template(ordersTemplate),
initialize: function() {
_.bindAll(this);
Orders.fetch({ success: function() {
console.log(Orders.models)
}});
},
});
return OrdersView;
});
Orders.fetch won't populate the collection, though browser detects XHR json/items:
I already tried this solution Backbone.js + Rest. Collection is not populated after fetch() but still it won't work. Is there any way it can fetch data and populate it automatically to the collection? Or am I missing something?
PS: sorry for the brute code posting...
EDIT: success callback on fetch won't do anything but json/items just called by XHR on browser
EDIT: update code on order.js, removed the STORE param
EDIT: i appreciate if you can look on to this url http://mindanaojobs.net/backbone/ and inspect something in it, jsfiddle seems a little bit tricky
Does the XHR response contain an array of objects? If there is any kind of object wrapper like
{items: [{...}, {...}]}
then you need to implement the parse method accordingly.
Yes, I looked at your code and you need this in your Orders collection:
parse: function (response) { return response.items;}

Update model with Mongoose, Express, NodeJS

I'm trying to update an instantiated model ('Place' - I know it works from other routes) in a MongoDB and have spent a while trying to properly do so. I'm also trying to redirect back to the page that views the 'place' to view the updated properties.
Node v0.4.0, Express v1.0.7, Mongoose 1.10.0
Schema:
var PlaceSchema = new Schema({
name :String
, capital: String
, continent: String
});
Controller/route:
app.put('/places/:name', function(req, res) {
var name = req.body.name;
var capital = req.body.capital;
var continent = req.body.continent;
Place.update({ name: name, capital: capital, continent: continent}, function(name) {
res.redirect('/places/'+name)
});
});
I've tried a bunch of different ways but can't seem to get it.
Also, isn't how I declare the three {name, capital, and continent} variables blocking further operations? Thanks. General debugging help is also appreciated. Console.log(name) (right below the declaration) doesn't log anything.
Jade form:
h1 Editing #{place.name}
form(action='/places/'+place.name, method='POST')
input(type='hidden', name='_method', value='PUT')
p
label(for='place_name') Name:
p
input(type='text', id='place_name', name='place[name]', value=place.name)
p
label(for='place_capital') Capital:
p
input(type='text', id='place_capital', name='place[capital]', value=place.capital)
p
label(for='place_continent') Continent:
p
textarea(type='text', id='place_continent', name='place[continent]')=place.continent
p
input(type="submit")
You have to find the document before updating anything:
Place.findById(req.params.id, function(err, p) {
if (!p)
return next(new Error('Could not load Document'));
else {
// do your updates here
p.modified = new Date();
p.save(function(err) {
if (err)
console.log('error')
else
console.log('success')
});
}
});
works for me in production code using the same setup you have. Instead of findById you can use any other find method provided by mongoose. Just make sure you fetch the document before updating it.
Now, i think you can do this :
Place.findOneAndUpdate({name:req.params.name}, req.body, function (err, place) {
res.send(place);
});
You can find by id too :
Place.findOneAndUpdate({_id:req.params.id}, req.body, function (err, place) {
res.send(place);
});
So now you can find and update directly by id, this is for Mongoose v4
Place.findByIdAndUpdate(req.params.id, req.body, function (err, place) {
res.send(place);
});
Just to mention, if you needs updated object then you need to pass {new: true} like
Place.findByIdAndUpdate(req.params.id, req.body, {new: true}, function (err, place) {
res.send(place);
});
I think your problem is that you are using node 0.4.0 - try moving to 0.2.6 with an it should work. There is an issue logged on github with the bodyDecoder not populating the req.body.variable field in node >= 0.3.0.