I have been writing an app which uses the lookback tool to get the total number of points a project had within it on a certain date. The request to pull this information looks as follows:
getPointsOn: function(date, iOIDs, callback) {
var params = {};
params.find = '{ Iteration: {$in: [' + iOIDs + ']}, PlanEstimate: { $gt: 0 }, __At: "' + date.toISOString() + '" }';
params.fields = '[ "PlanEstimate", "Project" ]';
Ext.Ajax.cors = true;
Ext.Ajax.request({
url: App.qURL,
method: 'GET',
params: params,
withCredentials: true,
success: function(response) {
var points = {};
Ext.Array.each(Ext.JSON.decode(response.responseText).Results, function(US) {
if (points[US.Project] == undefined) points[US.Project] = 0;
points[US.Project] += US.PlanEstimate;
});
callback(points);
},
failure: function() {
console.log('Ajax Failed');
callback({});
}
});
}
It returns an object with Project/Points pairs and works perfectly when 1-2 iteration ObjectIDs are passed to it. The problem is when I start requesting larger data sets. I have been getting the "Request Entity Too Large" error. I assume this is a problem with the request itself although I'm not sure how it could be "too large". What is the likely cause of this error?
Thanks!
You can do an Ext.util.Cookies.clear(cookieName) to remove a cookie. Generally the maximum request size for ALM is 8k so a large pref cookie combined with a large number of iteration oids could hit that limit.
Also, there is a more fully supported way to access the Lookback API in SDK 2.0p4.
http://developer.rallydev.com/apps/2.0p4/doc/#!/api/Rally.data.lookback.SnapshotStore
Ext.create('Rally.data.lookback.SnapshotStore', {
listeners: {
load: function(store, data, success) {
//process data
}
},
fetch: ['PlanEstimate', 'Project'],
filters: [
{
property: 'Iteration',
operator: 'in',
value: iOIDS //an array
},
{
property: 'PlanEstimate',
operator: '>',
value: 0
},
{
property: '__At',
value: date.toISOString()
},
],
autoLoad: true
});
Large state elements, such as the values selected from a picker, should be stored with a Ext.state.LocalStorageProvider instance, rather than a Ext.state.CookieProvider. Assuming that the cookie does not need to be sent to fulfill the query request.
Related
Having two issues with this. One is that I keep getting an error when trying to upload my script. The other is that one version that I did get to upload, didn't load any value into the field (ie. field blank after script ran)
The error I keep getting on upload is "Fail to evaluate script: All SuiteScript API Modules are unavailable while executing your define callback." And although I've made drastic changes to the script, it still won't allow me to upload.
/**
*#NApiVersion 2.x
*#NScriptType ScheduledScript
*/
define(['N/search', "N/record"],
function(search, record) {
function loadAndRunSearch(scriptContext) {
var mySearch = search.load({
id: 'customsearch1088'
});
mySearch.run().each(function (result) {
var countt = result.getValue({
name: 'number'
});
var entity = result.getValue({
name: 'internalid'
});
var objRecord = record.load({
type: record.Type.CUSTOMER,
id: entity,
isDynamic: true,
});
var vfield = objRecord.getField({
fieldId: 'custentity_orders_12m'
});
objRecord.setValue({fieldId: 'custentity_orders_12m', value: countt});
objRecord.save();
});
}
return {
execute: loadAndRunSearch
};
});
That's the script stripped down to the bare bones (FYI still doesn't upload), and the script that uploaded was basically a more complicated version of the same script, except it didn't set the field value. Can anyone see where I've gone wrong?
You haven't returned the entry function.
/**
*#NApiVersion 2.x
*#NScriptType ScheduledScript
*/
define(['N/search', 'N/record'],
function(search, record) {
function loadAndRunSearch(scriptContext) {
var mySearch = search.load({
id: 'customsearch1088'
});
mySearch.run().each(function (result) {
var countt = result.getValue({
name: 'number'
});
var entity = result.getValue({
name: 'internalid'
});
record.submitField({
type: record.Type.CUSTOMER,
id: entity,
values: {
'custentity_orders_12m' :countt
}
});
});
}
return {
execute : loadAndRunSearch
}
});
I wanted to trigger a Jenkins job through the Jenkins API
we can do that by hitting the URL similar to "JENKINS_URL/job/JOBNAME/build"
I want to hit the API via Google action/Dialogflow.
Is there any tutorial available to do a similar process that I want to achieve?
You should take a look at the Dialogflow quotes sample, which shows how to make external API calls:
// Retrieve data from the external API.
app.intent('Default Welcome Intent', (conv) => {
// Note: Moving this fetch call outside of the app intent callback will
// cause it to become a global var (i.e. it's value will be cached across
// function executions).
return fetch(URL)
.then((response) => {
if (response.status < 200 || response.status >= 300) {
throw new Error(response.statusText);
} else {
return response.json();
}
})
.then((json) => {
// Grab random quote data from JSON.
const data = json.data[Math.floor(Math.random() * json.data.length)];
const randomQuote =
data.quotes[Math.floor(Math.random() * data.quotes.length)];
conv.close(new SimpleResponse({
text: json.info,
speech: `${data.author}, from Google ` +
`Developer Relations once said... ${randomQuote}`,
}));
if (conv.screen) {
conv.close(new BasicCard({
text: randomQuote,
title: `${data.author} once said...`,
image: new Image({
url: BACKGROUND_IMAGE,
alt: 'DevRel Quote',
}),
}));
}
});
});
The following Node.js code:
var request = require('request');
var getLibs = function() {
var options = { packages: ['example1', 'example2', 'example3'], os: 'linux', pack_type: 'npm' }
request({url:'http://localhost:3000/package', qs:options},
function (error , response, body) {
if (! error && response.statusCode == 200) {
console.log(body);
} else if (error) {
console.log(error);
} else{
console.log(response.statusCode);
}
});
}();
sends the following http GET request query that is received by like this:
{"packages"=>{"0"=>"example1", "1"=>"example2", "2"=>"example3"}, "os"=>"linux", "pack_type"=>"npm"}
How can I optimize this request to be received like this:
{"packages"=>["example1", "example2", "example3"], "os"=>"linux", "pack_type"=>"npm"}
Note. The REST API is built in Ruby on Rails
If the array need to be received as it is, you can set useQuerystring as true:
UPDATE: list key in the following code example has been changed to 'list[]', so that OP's ruby backend can successfully parse the array.
Here is example code:
const request = require('request');
let data = {
'name': 'John',
'list[]': ['XXX', 'YYY', 'ZZZ']
};
request({
url: 'https://requestb.in/1fg1v0i1',
qs: data,
useQuerystring: true
}, function(err, res, body) {
// ...
});
In this way, when the HTTP GET request is sent, the query parameters would be:
?name=John&list[]=XXX&list[]=YYY&list[]=ZZZ
and the list field would be parsed as ['XXX', 'YYY', 'ZZZ']
Without useQuerystring (default value as false), the query parameters would be:
?name=John&list[][0]=XXX&list[][1]=YYY&list[][2]=ZZZ
I finally found a fix. I used 'qs' to stringify 'options' with {arrayFormat : 'brackets'} and then concatinated to url ended with '?' as follows:
var request = require('request');
var qs1 = require('qs');
var getLibs = function() {
var options = qs1.stringify({
packages: ['example1', 'example2', 'example3'],
os: 'linux',
pack_type: 'npm'
},{
arrayFormat : 'brackets'
});
request({url:'http://localhost:3000/package?' + options},
function (error , response, body) {
if (! error && response.statusCode == 200) {
console.log(body);
} else if (error) {
console.log(error);
} else{
console.log(response.statusCode);
}
});
}();
Note: I tried to avoid concatenation to url, but all responses had code 400
This problem can be solved using Request library itself.
Request internally uses qs.stringify. You can pass q option to request which it will use to parse array params.
You don't need to append to url which leaves reader in question why that would have been done.
Reference: https://github.com/request/request#requestoptions-callback
const options = {
method: 'GET',
uri: 'http://localhost:3000/package',
qs: {
packages: ['example1', 'example2', 'example3'],
os: 'linux',
pack_type: 'npm'
},
qsStringifyOptions: {
arrayFormat: 'repeat' // You could use one of indices|brackets|repeat
},
json: true
};
I'm trying to get a combined record set from User Stories and Defects. I have filters for each that work (e.g. Defect State != Closed and User Story Direct Child Count = 0) but I'm unable to have a combined query or custom query that will work. For example, the following code brings back User Stories but inherently filters out all defects.
I'm sure there are multiple ways of doing this but how do you get a combined result set of multiple types with filters specific for each type? Thanks.
_getData: function(name) {
var deferred = Ext.create('Deft.Deferred');
Ext.create('Rally.data.wsapi.artifact.Store', {
models: ['UserStory', 'Defect'],
pageSize: 2000,
fetch: ['c_MyCustomField', 'ScheduleState', 'PlanEstimate', 'Name'],
filters: [
{ property: 'ScheduleState', operator: '!=', value: 'Accepted' },
function(item){
var dirChildCountIsGood = false;
try
{
if (item.DirectChildrenCount > 0)
dirChildCountIsGood = false;
}
catch(ex) {}
return false;
},
/* or */{ property: 'DirectChildrenCount', operator: '=', value: '0' }
//{ property: 'State', operator: '!=', value: 'Closed' }
],
sorters: [
{ property: 'c_MyCustomField', direction: 'ASC'} // Same field for both User Stories and Defects
],
autoLoad: true,
listeners: {
scope: this,
load: this._onRecordsLoaded
}
});
console.log('Call to WSAPI store complete.');
return deferred;
}
This is an unfortunate weirdness with the artifact endpoint. You can work around it by using a special hidden TypeDefOid attribute in your query to get the various clauses to only apply to the correct types. Longer term we hope to make enhance the WSAPI query language to better support this type of scenario.
Build two filters like so:
var nonClosedDefectsFilter = Rally.data.wsapi.Filter.and([
{
property: 'TypeDefOid',
value: 12345 //replace with your defect typedef oid
},
{
property: 'State',
operator: '!='
value: 'Closed'
}
]);
var leafStoryFilter = Rally.data.wsapi.Filter.and([
{
property: 'TypeDefOid',
value: 23456 //replace with your story typedef oid
},
{
property: 'DirectChildrenCount',
value: 0
}
]);
And then or them together when you pass them to your store at creation time:
Ext.create('Rally.data.wsapi.artifact.Store', {
//other config from above omitted for brevity
filters: [nonClosedDefectsFilter.or(leafStoryFilter)]
});
I am getting Loading failed error when searching for something in a select2 box using ajax. My code is as follows:
$("#drugSearch").select2({
placeholder: "Search for a drug by drug id or name",
minimumInputLength: 3,
ajax: {
url: "#Url.Action("SearchDrug", "Drug")",
dataType: 'jsonp',
quietMillis: 100,
data: function (term, page) {
return {
query: term
};
},
results: function (data, page) {
debugger;
return {
results: data.drugs
};
}
},
formatResult: drugResult,
formatSelection: drugSelection,
escapeMarkup: function (m) { return m; }
});
function drugResult(drug) {
debugger;
return drug.Name + " (" + drug.DrugBankRef + ")";
}
function drugSelection(drug) {
debugger;
return drug.Name + " (" + drug.DrugBankRef + ")";
}
The breakpoints are also not hitting the above debugger; lines
My JSON is returned as:
{ drugs: {[...]} }
It also has the properties Name and DrugBankRef and I have confirmed a valid JSON is returned from the URL after searching.
What am I doing wrong here? Anything else you need to trace the issue?
I was using JSONP instead of JSON, changing the data type to JSON fixed the issue.
It is not an error. There is a real difference between JSON and JSONP. In JSONP, your JS will send in a supplementary parameter, named callback, that contains the name of expeted enclosing function name.
Select2 supports the two modes :
JSON, which expects { drugs: {[...]} } as data
JSONP, which provide a callbackName and expects callbackName({ drugs: {[...]} }); as data
Both works, and are correct, differents, way of processing.
Feel free to read http://en.wikipedia.org/wiki/JSONP