How to give configurable URL in tableau WDC - tableau-api

I am trying to build a tabeau WDC.
this is my code
(function () {
var myConnector = tableau.makeConnector();
myConnector.getSchema = function (schemaCallback) {
var cols = [{
id: "month",
dataType: tableau.dataTypeEnum.string
}, {
id: "value1",
alias: "value1",
dataType: tableau.dataTypeEnum.float
}, {
id: "value2",
alias: "value2",
dataType: tableau.dataTypeEnum.float
}];
var tableSchema = {
id: "testfeed",
alias: "test Feed",
columns: cols
};
schemaCallback([tableSchema]);
};
myConnector.getData = function (table, doneCallback) {
$.getJSON('http://test.com/view?name=test&filters=[{"type":"number","id_equals":["123"]}]', function (resp) {
var feat = resp.DATA,
tableData = [];
// Iterate over the JSON object
for (var i = 0, len = feat.length; i < len; i++) {
tableData.push({
"MONTH": feat[I].month,
"ChargeEntryLag_NUMERATOR": feat[i]. value1,
"ChargeEntryLag_DENOMINATOR": feat[i]. value2
});
}
table.appendRows(tableData);
doneCallback();
});
};
tableau.registerConnector(myConnector);
$(document).ready(function () {
$("#submitButton").click(function () {
tableau.connectionName = "testFeed";
tableau.submit();
});
});
})();
my URL contains some filters as shown in the above code, so if U want to get data for a particular filter I have to hardcode it in URL and the use it.
In other word my URL is static , Is there a way to make it dynamic.
suppose I want the value of 'id' to be 10in my filter, for that I have to go the the WDC code and change it. can it be made configurable.

use tableau.connectionData to pass data. There is an example in this tutorial:
https://tableau.github.io/webdataconnector/docs/wdc_multi_table_tutorial
Typically you'd create a form. When you connect with the WDC in tableau desktop, you put in the URL of your form. The form will store the form vars in tableau.connectData. Your getData can then take those and create a custom Data Source inside tableau desktop for you.
- Mike

Related

Storing JSON in MongoDB

I m trying to store some data in MongoDB, I am not sure of the type of data that I am being provided with as I am getting it from a formbuilder(https://github.com/kevinchappell/formBuilder) that I am using.
I am getting the data from:
document.getElementById('getJSON').addEventListener('click', function() {
var ans = formBuilder.actions.getData('json', true);
//console.log(ans);
//var ans2 = JSON.parse(ans);
alert(ans);
console.log(ans);
$.ajax({
type: "POST",
data: ans,
url: "/j",
success: function(){
console.log('success');
}
});
document.forms["myForm"].submit();
});
It reaches my back end as so:
//FETCHING THE JSON OF THE CLAUSE FORM CREATED BY THE ADMIN
router.post('/j', function(req, res, next) {
req.session.fdata = req.body; //JSON FETCHED FROM JAVASCRIPT USING AJAX, STORED IN SESSION
if(req.session.fdata==null) //CHECKING IF WE ARE RECEIVING VALUES
{
res.redirect('/admin');
}
else {
mongo.connect(url, function (err, db) {
assert.equal(null, err);
//var jfdata = JSON.parse(req.session.fdata);
db.collection('clauses').insertOne(req.session.fdata, function (err, result) {
console.log('New Clause Added');
console.log(req.session.fdata);
db.close();
});
});
res.redirect('/admin');
}
});
I insert it into the DB and it looks fine in the DB but on retrieval I cant seem to access the inner portions of the data. Is my data in the wrong format? Is it JSON or a JS object?
it looks like so in the DB:(the db is empty before insertion)enter image description here
This is what the console prints
[ { _id: 596de520ef77eb2614cd1e47,
'[\n\t{\n\t\t"type": "number",\n\t\t"label": "Number",\n\t\t"description":
"total number",\n\t\t"placeholder": "0",\n\t\t"className": "form-
control",\n\t\t"name": "number-1500374279764"\n\t}\n]': '' },
{ _id: 596de520ef77eb2614cd1e48 } ]
The data you are trying to save does not seem right to me.
What you are getting is a string of the JSON object.
You have to use JSON.parse to convert it to a proper JSON object.
JSON.parse('[\n\t{\n\t\t"type": "number",\n\t\t"label":"Number",\n\t\t"description": "total number",\n\t\t"placeholder": "0",\n\t\t"className": "form-control",\n\t\t"name": "number-1500374279764"\n\t}\n]')
After that, you can form the data and insert in DB.
var query = {
array : [{"type": "number",
"label": "Number",
"description": "total number",
"placeholder": "0",
"className": "form-control",
"name": "number - 1500374279764"}]
}
db.collection('clauses').insertOne(query, function (err, result)
{
db.close();
});
Let me know if it helps!

Why my filter is not working in v2.ODataModel "read"?

I am using the OData model to read data. But it doesn't work. Check the code below:
getGuid: function(pernr) {
var self = this;
var url = "/PersonalDetailSet?$filter=Pernr eq '00000001'";
self.setBusy(true);
this.oModel.read(url, {
success: function(res) {
// ...
},
error: function() {
// ...
}
});
}
I don't know why the filter in url is not working now?
Check if your OData service supports the $filter query in the first place.
Use the read method correctly:myV2ODataModel.read("/PersonalDetailSet"/* No $filter queries here! */, {
filters: [ // <-- Should be an array, not a Filter instance!
new Filter({ // required from "sap/ui/model/Filter"
path: "myField",
operator: FilterOperator.EQ, // required from "sap/ui/model/FilterOperator"
value1: "..."
})
],
// ...
});
API reference: sap.ui.model.odata.v2.ODataModel#read
API reference: sap.ui.model.Filter
First you check whether you are getting model in the scope or not. As i can see this.oModel which is not proper way of getting model. Better use this.getModel() or this.getView().getModel() and then check the call. Passing filter is not the right way but still it should work.
If you want to apply additional URL Parameters in the read function you have to do this via the "urlParameters" parameter:
getGuid: function(pernr){
var self = this;
var url = "/PersonalDetailSet";
self.setBusy(true);
this.oModel.read(url, {
urlParameters: {
"$filter" : "Pernr eq '00000001'"
},
success: function(res){
self.setBusy(false);
self.guid = res.results[0].Guid;
},
error: function() {
self.setBusy(false);
}
});
}

Sails js bulk upload and insert into MongoDB

Hi In my Sailsjs application there is bulk upload feature where a admin can upload csv file. I am using csv-parse for parsing the csv content.
Now i want to insert the data into Mongo DB where each row has Vehicle Info and Test Info. These two models have one to many relationship. I am not able to figure out how to insert them into DB. Below is my code for inserting the vehicle.
Below is the code sample i was thinking to create VehicleTest model once Vehicle model is created but i don't have access to vehicle to get info for vechileTest model
Vehicle Model
attributes: {
make: {
type: "string",
required: true
},
tests :{
collection: 'VehicleTest',
via : 'vehicleTested'
},
VechileTest model
attributes: {
vehicleTested :{
modal :'Vehicle',
required:true
},
Below lines of code from the function reads the file and parse it
var parse = require('csv-parse');
var fs = require("fs")
var createdVehicle =[];
var stream = files[0].fd;
fs.readFile(stream, 'utf8', function (err, data) {
// Print the contents of the file as a string here
// and do whatever other string processing you want
parse(data, {columns: true,delimiter:'|'}, function(err, output){
if(output.length>0)
{
for (var i = 0, len = output.length; i < len; i++) {
var vehicle_TestInfo = output[i];
//console.log(vehicle_TestInfo);
//
Vehicle.create({make : vehicle_TestInfo.make,model:vehicle_TestInfo.model,year:vehicle_TestInfo.year ,engineFuel:vehicle_TestInfo.engineFuel,obdZone:vehicle_TestInfo.obdZone,generation:vehicle_TestInfo.generation,protocol:vehicle_TestInfo.protocol,onStar:vehicle_TestInfo.onStar}).exec(function(err,vehCreated){
console.log(vehCreated);
//VehicleTest.Create({vehicleTested:vehCreated._id,overAllComp:vehicle_TestInfo.overAllComp,deviceGeneration:vehicle_TestInfo.deviceGeneration}).exec(function(err,testCreated){
//
// console.log(testCreated);
//
//})
});
}
}
this is how i implemented
for (var i = 0, len = output.length; i < len; i++) {
var vehicle_TestInfo = output[i];
//console.log(vehicle_TestInfo);
//
Vehicle.create({make : vehicle_TestInfo.make,model:vehicle_TestInfo.model,year:vehicle_TestInfo.year ,trim:vehicle_TestInfo.trim ,engineFuel:vehicle_TestInfo.engineFuel,obdZone:vehicle_TestInfo.obdZone,generation:vehicle_TestInfo.generation,protocol:vehicle_TestInfo.protocol,onStar:vehicle_TestInfo.onStar,
tests : {deviceGeneration:vehicle_TestInfo.deviceGeneration,overAllComp:vehicle_TestInfo.overAllComp,isTested:vehicle_TestInfo.isTested,testingInferred:vehicle_TestInfo.testingInferred,vinRead:vehicle_TestInfo.vinRead,
odoRead:vehicle_TestInfo.odoRead,pidRead:vehicle_TestInfo.pidRead,doorLocked:vehicle_TestInfo.doorLocked,SeatBelt:vehicle_TestInfo.seatBelt,fuelLevel:vehicle_TestInfo.fuelLevel,issueType:vehicle_TestInfo.issueType,degreeOfERGIntr:vehicle_TestInfo.degreeOfERGIntr,dataLoggerModel:vehicle_TestInfo.dataLoggerModel,
numberOfVehicle:vehicle_TestInfo.numberOfVehicle,remarks:vehicle_TestInfo.remarks}}).exec(function(err,vehCreated){
if(err && err.originalError && err.originalError.code===50)
{
Vehicle.update({id:vehCreated.id})
}
/// console.log(vehCreated);
// vehCreated.tests.add({})
createdVehicle.push(vehCreated);
});

Grouping by month on extjs grid

I have a grid, which has a payments store. The Payment model, which it's store uses, has a field which is a date.
I've already implemented grouping by date, but that gives me a group of entries for each day, like this...
What I want to do is have a group for each month instead of each day.
Any ideas on how to do this?
Ok, nevermind. I just found a way to do this. I created a field using convert to find the month of the payment and used that field as the grouping field.
I'll leave this posted in case anyone ever needs it.
This is the Payment model...
Ext.define('Ext.model.Payment',{
extend: 'Ext.data.Model',
requires: [
'Ext.data.Field'
],
fields: [
{
name: 'n_id_payment',
type:'integer'
},{
name: 'n_amount',
type:'integer'
}.....,
..... Several other fields .....
},{
name:'payment_month',
type:'date',
convert:function(model, record){
var today = new Date(record.data.dt_date);
var dd = today.getDate();
var mm = today.getMonth();
var month=new Array();
month[0]="Enero";
month[1]="Febrero";
month[2]="Marzo";
month[3]="Abril";
month[4]="Mayo";
month[5]="Junio";
month[6]="Julio";
month[7]="Agosto";
month[8]="Septiembre";
month[9]="Octubre";
month[10]="Noviembre";
month[11]="Diciembre";
return month[mm];
}
}
]
})
And this is the payment store...
Ext.define('Ext.store.PaymentsStore', {
extend: 'Ext.data.Store',
requires: [
'Ext.model.Payment',
'Ext.data.proxy.Memory'
],
constructor: function(cfg) {
var me = this;
cfg = cfg || {};
me.callParent([Ext.apply({
autoLoad: false,
async:false,
groupField:'payment_month',
model: 'Ext.model.Payment',
method:'POST',
proxy: {
isSynchronous:true,
type: 'ajax',
url: 'http://localhost/index.php/TblPayment/fetch',
reader:{
type :'json',
method:'POST'
}
}
}, cfg)]);
}
});
This is the groupingFeature config...
var groupingFeature = Ext.create('Ext.grid.feature.Grouping', {
groupHeaderTpl:'{name}'
});
The grid should have this property set too features: [groupingFeature]
And in case you're stuck with an error with grouping, something about getRowStyleTableEl being null... There's a workaround for that issue...
Ext.override(Ext.view.Table, {
/*
Temporary fix for bug in ExtJS 4.2.1. See: sencha.com/forum/showthread.php?264657-Exception-When-Selecting-First-Grid-Row
*/
getRowStyleTableElOriginal: Ext.view.Table.prototype.getRowStyleTableEl,
getRowStyleTableEl: function() {
var el = this.getRowStyleTableElOriginal.apply(this, arguments);
if (!el) {
el = {
addCls: Ext.emptyFn,
removeCls: Ext.emptyFn,
tagName: {}
}
}
return el;
}
});

Backbone pagination

can anyone explain to me how this backbone.paginator example works?
https://github.com/backbone-paginator/backbone.paginator/blob/master/examples/request-paging/collections/PaginatedCollection.js
I see that the backend can be reached using the URL:
paginator_core: {
type: 'GET',
dataType: 'jsonp',
url: 'https://api.github.com/repos/twitter/bootstrap/issues?'
},
But what/where does this example pass the page number and amount of itmes to retreive from the backend? My backend is accessible through the following restfull url: and i cant figure out how the next page details are inserted in the url above...
www.test.com/getItems/{query}/{from}/{size}
Is this automatically inserted by the paginator plugin?
Just check internal implementation for fetch method
// map params except directions
var queryParams = this.mode == "client" ?
_pick(this.queryParams, "sortKey", "order") :
_omit(_pick(this.queryParams, _keys(PageableProto.queryParams)),
"directions");
var i, kvp, k, v, kvps = _pairs(queryParams), thisCopy = _clone(this);
for (i = 0; i < kvps.length; i++) {
kvp = kvps[i], k = kvp[0], v = kvp[1];
v = _isFunction(v) ? v.call(thisCopy) : v;
if (state[k] != null && v != null) {
data[v] = state[k];
}
}
request creates based on
queryParams: {
currentPage: "page",
pageSize: "per_page",
totalPages: "total_pages",
totalRecords: "total_entries",
sortKey: "sort_by",
order: "order",
directions: {
"-1": "asc",
"1": "desc"
}
},
property - thus current collection state mapps over setting from queryParams for generations url