Execute SPARQL Query with vue.js - javascript

I want to make a website by implementing the use of sparql in vue js. The scenario I want is to create a special place to write Sparql Query and then execute it with vue.js. Is all that possible? if possible how should i start it? if not possible, is there any other alternative than using vue.js? Please help.

I am not a JS pro by any means. Anyway, for a similar problem, I used axios for the HTTP request.
This worked fine for my use case. Anyway, you will find a precise description of the JSON format at https
var params = new URLSearchParams();
// queryArtistsByNameTpl contains the actual SPARQL query,
// with $artistName as a placeholder
let similarGroupsQuery = queryArtistsByNameTpl.replace("$artistName", this.artistName);
params.append('query', similarGroupsQuery);
let getArtistsHandler = sparqlResponseHandler(this, 'artistList');
axios.post(sparqlEndPoint, params).then(getArtistsHandler);
function sparqlResponseHandler(currentObj, currList) {
return function(response) {
const rows = response.data.results.bindings;
currentObj[currList] = [];
if (rows.length > 0) {
rows.forEach(function(item, index) {
var record = {};
for (var prop in item) {
if (item.hasOwnProperty(prop)) {
record[prop] = item[prop].value;
}
}
currentObj[currList].push(record);
})
} else {
console.log("no data from SPARQL end point");
}
}
}
The JSON resturned by SPARQl endpoints is specified in https://www.w3.org/TR/sparql11-results-json/ , which is rather short and very understandable.
The code can certainly be improved by someone more knowledgeable then me, but it was fine for the tech demo we used it for.

Related

Multiple Calls For Web Data Connectors Tableau using Java Script Promises

I wrote a Web Data Connector that queries an API and gets data for a symbol that is passed in via URL.
However, I want to extend the API to get more than one symbol worth of data, but the way the API is structured, I would need to make multiple calls to this in the URL which means one getJSON call per symbol. I have tried wrapping the calls into a for loop and running the call for every symbol. This works fine when I run it in Simulator, but when I run this in Tableau Desktop, it returns just one symbol. I found one solution that this kind of issue can be solved using Promises, but I’m new in Java Script and I wasn’t able to figure out how to exactly apply this to my code. I provided that part of the code below, can anyone give me some ideas how can I use promises?
// Download the data
myConnector.getData = function(table, doneCallback) {
var dataObj = JSON.parse(tableau.connectionData);
const base_url = "https://myurl/getData.json?";
var copiedObj = Object.assign({}, dataObj);
console.log(copiedObj)
delete copiedObj.symbol;
delete copiedObj.apikey;
var symbols = dataObj.symbol.split(',');
for ( let i = 0; i < symbols.length; i ++){
dataString = base_url + "apikey="+ dataObj.apikey + "&symbol=" + symbols[i];
const url_test = new URL(dataString);
for (const [key,value] of Object.entries(copiedObj)){
url_test.searchParams.set(key,value);
}
const apiCall = url_test.href;
$.getJSON(apiCall, function(resp) {
var feat = resp.results,
tableData = [];
// Iterate over the JSON object
for (var i = 0, len = feat.length; i < len; i++) {
tableData.push({
"attribute1”: feat[i].attribute1,
“attribute2”: feat[i].attribute2,
“attribute3”: feat[i].attribute3,
“attribute4”: feat[i].attribute4,
});
}
table.appendRows(tableData);
doneCallback();
});
}
};

Deserialize DeepObject Querystring Keys in Azure Functions / Javascript

We are constructing an API with Azure Functions, and the spec calls for DeepObject references in the GET request's querystring. So, the structure looks like https://example.com/api/persons?name[first]=Todd. The expectation is that some of the query keys may be DeepObject references, others will be flat.
This is a pattern that apparently Express can handle, but Azure Functions uses an ASP.NET router. The expectation is that the reference above should deserialize into req.params: { name: { first: "Todd" } }. However, instead the output looks like req.params: { "name[first]": "Todd" }.
I would really love to not have to regex/search each key, so does anyone know if:
There's a config/flag in ASP.NET to support this structure?
There's a good pattern in Javascript to deserialize this in some functional -- or at least non-idiosyncratic -- way?
Note: Anyone who suggest some use of the eval() method will not be selected. But for playing you will take home a comment with a Nineties reference, because that was the last decade the use of the that method was considered acceptable. :stuck_out_tongue_winking_eye:
For this problem, I don't think we can change some configuration to support this structure. What we can do is to implement in code by ourselves.
Here is my function code:
module.exports = async function (context, req) {
console.log("======query url is:" + req.url);
const result = queryStringToJSON(req.url);
console.log(result);
context.res = {
body: "success"
};
}
function queryStringToJSON(queryUrl) {
if(queryUrl.indexOf('?') > -1){
var queryString = queryUrl.split('?')[1];
}
var pairs = queryString.split('&');
var result = {};
pairs.forEach(function(pair) {
if (pair.indexOf('[') > -1) {
var nameObj = {};
var firstObj = {};
var nameStr = pair.substring(0, pair.indexOf('['));
var firstStr = pair.substring(pair.indexOf('[')+1, pair.indexOf(']'));
firstObj[firstStr] = pair.split('=')[1];
nameObj[nameStr] = firstObj;
Object.assign(result, nameObj);
}else {
pair = pair.split('=');
result[pair[0]] = decodeURIComponent(pair[1] || '');
}
});
return result;
}
Start the function project, I request it with http://localhost:7071/api/HttpTrigger1?name[first]=Todd&email=test#mail.com. The result shows:
After much searching, I wasn't able to find any way to natively implement this in the ASP.NET router. Though there is a great deal of suggestions on how to deserialize this structure directly in your ASP.NET controller functions, I am working in Javascript.
What was helpful was the qs library, available in NPM, which supports a number of nuances related to this query string structure.
const { query } = req;
// => { "name[first]": "Todd" };
const deserializedQuery = qs.parse(query);
// => { name: { first: "Todd" }
Equally helpful to me is that I need a way to restructure my outbound query string in this same format. Qs works with the paramsSerializer attribute in Axios.
const params = { name: { first: "Todd" };
const paramsSerializer = (params) => { return Qs.stringify(params); };
const reqOptions = { params, paramsSerializer };
axios.get("https://example.com/api/persons", reqOptions);
// => GET https://example.com/api/persons?name[first]=Todd
Thanks to #hury-shen for a completely workable solution. It just wasn't turnkey solution I was looking for.

How to check if item is out of date in cosmosDB using azure functions and the cosmos node sdk?

I currently have an item in the database that two users are trying to update. If one updates the item, I want the other user's update to fail then retry. I found a sample code for C# using the internal eTag, but I can't find the javascript equivalent.
https://github.com/Azure/azure-cosmos-dotnet-v3/blob/e22f9593a1245d3b1c98db78bacc89e4786d96e7/Microsoft.Azure.Cosmos.Samples/Usage/ItemManagement/Program.cs#L683-L734
Here is some pseudocode for what I want to do using the etag:
const patchItem = async function(container: Container, incomingItem: ItemData, currentItem: ItemData)
{
// state is an array of objects and this just adds to it
incomingItem.state.forEach(c => currentItem.state.push(c));
const appendedItem =
{
id: currentItem.id,
state: currentItem.state
_etag: currentItem._eTag
};
const { resource: updatedItem } = await container.item(incomingItem.id).replace(appendedItem, {IfMatchETag = appendedItem._eTag});
return updatedItem;
};
I am also reading the documentation on the change feed processor and wondering if there is a way I can read the item has been changed then fail the update. I'm not sure how to implement checking for changes in the change feed processor so any help with that would also be appreciated. Thank you!
I found the javascript equivalent for the etag and made the following fix:
const { resource: updatedItem } = await container.item(incomingItem.id).replace(appendedItem, { accessCondition: { type: "IfMatch", condition: currentItem._etag } });
Documentation found here:
https://learn.microsoft.com/en-us/azure/cosmos-db/sql-api-nodejs-samples
Code Example:
https://github.com/Azure/azure-cosmos-js/blob/master/samples/ItemManagement.ts#L98-L135

parsing json from multiple url using jquery

I want to parse json data from multiple url. I tried using for loop but it only parse json data from 1 url, while i want to show data from all urls.
I have a working script, but it is hardcoding. This is part of my script.
const apiex1 = 'http://www.ex.com/example1.json';
const apiex2 = 'http://www.ex.com/example2.json';
$.getJSON(apiex1, ex1Weather);
$.getJSON(apiex2, ex2Weather);
function ex1Weather(report) {
weatherData(report);
document.querySelector('tbody.ex1').innerHTML = apiWeather;
}
function ex2Weather(report) {
weatherData(report);
document.querySelector('tbody.ex2').innerHTML = apiWeather;
}
I have around 30 data/urls, using this script just overwhelming since the data will increase. What is the best way to make a better configuration for this script?
You should definitely use a loop over an array of URLs instead of hardcoding each one.
const apiUrls = ['http://ex.com/example1.json', 'http://ex.com/example2.json'];
apiUrls.forEach((url, index) => {
$.getJson(url, report => {
weatherData(report);
document.querySelector('tbody.ex' + index).innerHTML = apiWeather;
});
});

Tableau filter is not working for SETs that are created using Tableau Extension API

I have created an export to CSV extension in tableau to embed it into dashboard for users to download the data.
however we have condition and is, i need to set the filter using applyFilterAsync to some value before download and reset that filter using same applyFilterAsync with parameters of 'filtername' and 'value' and filterUpdateType.ADD to add and REMOVE to remove.
This is not working in case of SETs, Rangefilters, Dimensions and all.
Need your help resolve this issue.
Clearing the filters:
for (var i = 0; i < worksheets.length; i++) {
var sheet = worksheets[i];
if (sheetList.indexOf(sheet.name) > -1) {
sheet.getFiltersAsync());
sheet.clearFilterAsync('IN/OUT(DownloadSet)');
console.log('Filter Cleared');
}
}
Apply the filter after download:
sheet.applyFilterAsync('IN/OUT(DownloadSet)','In',tableau.FilterUpdateType.Replace);
Please your help to resolve this issue.
Thanks.
Since these are async functions, they return a promise. Your code should look like:
for (var i = 0; i < worksheets.length; i++) {
var sheet = worksheets[i];
if (sheetList.indexOf(sheet.name) > -1) {
sheet.getFiltersAsync())
.then(function() {
sheet.clearFilterAsync('IN/OUT(DownloadSet)');
})
.then(function() {
console.log('Filter Cleared');
})
}
}
Same with the applyFilterAsync:
sheet.applyFilterAsync('IN/OUT(DownloadSet)',['In'],tableau.FilterUpdateType.Replace)
.then(function() {
// do something
})
Without seeing more context/errors this is probably what is causing your issues.
EDIT: Set filters automatically evaluate to the 'In' value. I'm looking into if you have the right syntax for a set filter.
UPDATE:. This should be the right asynchronous call:
For applyFilterAsync you need to pass an array of strings, sheet.applyFilterAsync('IN/OUT(DownloadSet)',['In'],tableau.FilterUpdateType.Replace)

Categories