Rally SDK2.0 RC3 Query - filter

I'm having a hard time figuring out how to retrieve a set of stories using a tag name (TagName) as a filter. I have tried the following, but it always returns an empty store (the alert at the bottom returns []). Can someone help me figure out what I'm doing wrong?
var storyStore = Ext.create('Rally.data.wsapi.Store', {
model: "User Story",
fetch: true,
filters: [
{
property: 'Tags.Name',
operator: '=',
value: 'TagName'
}
]
});
storyStore.load({
callback: function(records, operation) {
if(!operation.wasSuccessful()) {
//process records
}
}
});
alert(JSON.stringify(storyStore.getRecords()));
Any help would be greatly appreciated!!!

This is due to the asynchronous nature of the store.load call. Your store and filters look totally right. Try putting your alert inside of the if statement within your callback. I bet you'll find there is data in there then:
storyStore.load({
callback: function(records, operation) {
if(operation.wasSuccessful()) {
alert(JSON.stringify(storyStore.getRecords()));
}
}
});

Related

Is there a way to use a named function with Hapi validation?

http://hapijs.com/tutorials/validation
I'd like to pass a function in to my validation block that checks for the presence of v as a source and confirms that account, profile and ipAddress are present. The docs say this is possible but don't have an example of using a function var to do it.
When I start up my API I get: Error: Invalid schema content: (account)
How can I use a named function to do validation in Hapi?
Code:
var validateQueryString;
validateQueryString = function(value, options, next) {
console.dir({
value: value,
options: options
});
// do some validation here
return next(null, value);
};
routes.push({
method: 'POST',
path: '/export/{source}/{start}/{end?}',
config: {
validate: {
query: {
account: validateQueryString,
profile: validateQueryString,
ipAddress: validateQueryString
},
params: {
source: joi.string().valid(['a', 'v', 't']),
start: joi.string().regex(utcDateTimeRegex),
end: joi.string().regex(utcDateTimeRegex)
}
}
},
handler: function(apiRequest, apiReply) {}
});
Tried other ways of calling this like:
account: function(value, options, next) {
return validateQueryString(value, options, next); }
with no luck.
I don't think you can have a single function to handle both at the same time.
Typically, the method for the full 'list' of query parameter. Here is a bit of code to illustrate:
function validateQuery(value, options, next){
console.log( 'validating query elements');
for (var k in value) {
console.log( k, '=', value[k]);
}
next(new Error(null, value);
}
And you set it as follow:
routes.push({
...
validate: {
query: validateQuery,
params: ...
}
...
}
Now, let's assume you hit http://server/myroute?a=1&b=2&c=3, you will get the following output:
validating query elements
a = 1
b = 2
c = 3
If you want to throw an error, you have to call next() as follow:
next( new Error('some is wrong'), value );
So the 'proper' way is to have a method for query and params, it seems.
Hope this helps.
I would recommend what you are doing is out of bounds of Joi's intent. Joi is targetted for schema validation against a JS object. What you want is runtime validation against rules that exist outside of the schema itself. Hapi has something built for this called server method. Leveraging server methods, you can apply your business validations there while separating the concerns of input model and output model shape validation through Joi.

Parse.com Slow Queries Analytics - Query with empty where-clause

my backend is made with parse.com Now I experienced in the Parse.com Analytics-Section the Tab "Slow Queries". Nice feature to see how your queries are performing.
Now what I see there is that there are queries of mine with empty where clauses you can see it here:
Users where:{ facebookID: ... }
Friends where:{ user: ... }
Friends where:{ objectId: ... }
Users where:{}
Friends_Rel where:{ friend: ..., user: ... }
Friends_Rel where:{}
Now my question is why are there empty where clauses? Because I assume that this Query results in an error and it is not wanted by me I think.
I always build my queries either like this:
var query = new Parse.Query("Friends_Rel");
query.equalTo("friend", friendID);
query.equalTo("user", userID);
query.find({
success: function(results) {
},
error: function(error) {
}
});
or like this:
var query = new Parse.Query("Users");
query.get(objectID, { // Gets row you're trying to update
success: function(row) {
},
error: function(row, error) {
}
});
Is there any explanation for this clauses where they could come from? Does the .get Method results in where:{}? I am not sure...
Closing as sunsetting parse.com

Sails.js and Waterline: dynamic validation by DB request

I use Sails 11.1 and Waterline 2.11.2 with a MongoDB database.
I would like to validate data inserted in my "Article" model using a in validator for 1 attribute.
Before, I was doing the job with lifecycle callbacks (beforeCreate and beforeUpdate especially), but it makes double code.
Here you have the model, truncated with just the attribute in question :
module.exports =
{
schema: true,
autoCreatedAt: false,
autoUpdatedAt: false,
attributes:
{
theme:
{
model: 'Theme',
required: true
}
}
}
I know how to define it statically:
in: ['something', 'something other']
I know how to call constants I defined in my constants.js file :
defaultsTo: function ()
{
return String(sails.config.constants.articleDefaultTheme);
}
But I would like to get all themes in my DB, to have a dynamic in validation. So, I wrote this :
theme:
{
model: 'Theme',
required: true,
in: function ()
{
Theme.find()
.exec(function (err, themes)
{
if (err)
{
return next({ error: 'DB error' });
}
else if (themes.length === 0)
{
return next({ error: 'themes not found' });
}
else
{
var theme_ids = [];
themes.forEach(function (theme, i)
{
theme_ids[i] = theme.theme_id;
});
return theme_ids;
}
});
}
}
But it's not working, I have always the "1 attribute is invalid" error. If I write them statically, or if I check in the beforeCreate method with another DB request, it works normally.
If I sails.log() the returned variable, all the themes ids are here.
I tried to JSON.stringify() the returned variable, and also to JSON.parse(JSON.stringify()) it. I also tried to convert the theme.theme_id as a string with the String() function, but nothing else...
What am I doing wrong? Or is it a bug?
You can also check my question here : Waterline GitHub issues
Models's configuration at your attributes scope at in field of course will throw an error, because it should not use a function, especially your function is not return anything, also if you force it to return something, it will return Promise that Theme.find()... did.
Try use different approach. There are exist Model Lifecycle Callbacks. You can use something like beforeCreate, or beforeValidate to manually checking your dynamic Theme, if it's not valid, return an error.
Or if it's achievable using standard DB relation, just use simple DB relation instead.

Backbone fetching data using a callback cursor

How would I use Backbones fetch to deal with callback results that contain a cursor? I'm going to use this simple example of a book that is fetching pages.
var Book = Backbone.Collection.extend({
model: Page,
recursiveFetch: function(cursor) {
this.fetch({
url: 'book/pages',
data: {
cursor: {cursor here};
},
success: function(response) {
if (response.cursor) {
this.recursiveFetch(response.cursor);
}
}
});
}
})
I need to be able to use fetch to keep fetching until the response doesn't contain a cursor. It should keep adding page models, but not replacing and overwriting them. It needs to do something like the example above, though I'm not sure of the best way to implement it.
I think that all you need to do is add in a {remove: false} into your fetch options. Its also worth mentioning that the this context of your success function may not be the collection, so you might want to pass it into the success function as a parameter. The end result would be:
recursiveFetch: function(cursor) {
this.fetch({
remove:false, // prevents removal of existing models
url: 'book/pages',
success: function(collection, response) {
if (response.cursor) {
collection.recursiveFetch(response.cursor);
}
}
});
}
The fix is very simple: add cursor to the parameters only when it's present. In other cases (i.e. the first time) make a normal request with the rest of the parameters.
var CursorCollection = Backbone.Collection.extend({
fetchAll: function(cursor) {
var params = {
// if you have some other request parameters...
};
// if we have a cursor from the previous call, add it to the parameters
if (cursor) { params.cursor = cursor; }
this.fetch({
remove: false,
data: params,
success: function(collection, response) {
if (response.cursor) {
return collection.fetchAll(response.cursor);
}
}
});
}
});
Then the first time you call it collection.fetchAll() and it recurses until it gets a response without a cursor.
Note, that the remove: false parameter is very important to accumulate the results as pointed out by #dcarson.

Breeze client-side custom validation with server-side data

I created a custom validator that check if a username is used on a DB.
The whole process of validation works. What is not working is result.
function createExistingUsernameValidator() {
var name = 'existingUsernameValidator';
var ctx = { messageTemplate: 'Questa partita I.V.A. o codice fiscale sono giĆ  stati inseriti.', displayName: "Partita IVA o Codice Fiscale" };
var val = new Validator(name, valFunction, ctx);
return val;
function valFunction(value, context) {
var result = ko.observable(true);
require('services/datacontext').getIsUserByUsername(value, result)
.then(function () {
debugger;
return !result();
});
}
}
The promise works: I know because it hits the debbugger line and the retunrnig value is correct.
But the validator always evaluate as false because I'm not returning anything when the validator is called. In other words: it won't wait for the promise.
Is it my bad javascript or something else?
Any help is welcome.
Thank you!
Edited after answer
I've come to a solution that involves Knockout Validation (very useful script).
function createIsExistingUserKoValidation() {
ko.validation.rules['existingUsername'] = {
async: true,
validator: function (val, params, callback) {
if (val) {
var result = ko.observable();
require('services/datacontext').getIsUserByUsername(val, result)
.then(function () {
callback(!result());
});
}
},
message: ' Existing username.'
};
ko.validation.registerExtenders();
}
In the entity creation:
var createDitta = function () {
var ditta = manager.createEntity(entityNames.ditta,
{
id: newGuid(),
legaleRappresentante: createPersona(),
isAttiva: true
});
ditta.pivaCodFiscale.extend({ existingUsername: { message: ' Existing username.', params: true } });
ditta.pivaCodFiscale.isValidating(false);
return ditta;
};
ditta.pivaCodFiscale.isValidating(false); this is needed because isValidating is initialized with true.
The problem is that your valFunction as written will ALWAYS return 'undefined'. ( which is 'falsy'.
The 'return !result()' expression is NOT the return value of 'valFunction', it is simply the result of an anonymous function that executes AFTER valFunction has already returned. This is the async nature of promises.
What you are trying is to write an 'asynchronous' validation which is NOT supported out of the box with Breeze, but the idea IS a good one.
I think that you might be able to accomplish what you want by having your async callback actually 'set' a value on the entity and have that set operation itself trigger a seperate 'synchronous' validation.
This IS a good idea for Breeze to support more naturally so please feel free to add a feature request to the Breeze User Voice for something like "asynchonous validation". We use this to gauge the communities interest in the various proposed features/extensions to Breeze.

Resources