Google drive picker API "this.qi is not a function" - google-drive-api

I am trying to load the google drive picker API in my project.
This source code is taken from Google Picker Code Sample
This is my source code.
gapiLoaded() {
window['gapi'].load('client:picker', this.intializePicker);
}
async intializePicker() {
await window['gapi'].client.load('https://www.googleapis.com/discovery/v1/apis/drive/v3/rest');
}
gisLoaded() {
this.tokenClient = window['google'].accounts.oauth2.initTokenClient({
client_id: MY_Client_Id,
scope: 'https://www.googleapis.com/auth/drive.readonly',
callback: '', // defined later
});
this.gisInited = true;
}
handleAuthClick() {
this.tokenClient.callback = async (response) => {
if (response.error !== undefined) {
throw (response);
}
this.accessToken = response.access_token;
this.createPicker();
};
if (this.accessToken === null) {
this.tokenClient.requestAccessToken({prompt: 'consent'});
} else {
this.tokenClient.requestAccessToken({prompt: ''});
}
}
createPicker() {
var view = window['google'].picker.View(window['google'].picker.ViewId.DOCS);
var picker = window['google'].picker.PickerBuilder()
.enableFeature(window['google'].picker.Feature.NAV_HIDDEN)
.enableFeature(window['google'].picker.Feature.MULTISELECT_ENABLED)
.setDeveloperKey('MY_APP_KEY')
.setAppId('MY_PROJECT_ID')
.setOAuthToken(this.accessToken)
.addView(view)
.addView( window['google'].picker.DocsUploadView())
.setCallback(this.pickerCallback)
.build();
picker.setVisible(true);
}
async pickerCallback(data) {
if (data.action === window['google'].picker.Action.PICKED) {
let text = `Picker response: \n${JSON.stringify(data, null, 2)}\n`;
const document = data[window['google'].picker.Response.DOCUMENTS][0];
const fileId = document[window['google'].picker.Document.ID];
console.log(fileId);
const res = await window['gapi'].client.drive.files.get({
'fileId': fileId,
'fields': '*',
});
text += `Drive API response for first document: \n${JSON.stringify(res.result, null, 2)}\n`;
console.log(text)
}
}
When I run this code, I am getting this error "this.Qi is not a function". The error arise at Picker builder function. How to resolve this?

Related

How to fix Community Connector Error in look studio?

I created api connector myself.
This is Code.gs file.
var cc = DataStudioApp.createCommunityConnector();
function getAuthType() {
var AuthTypes = cc.AuthType;
return cc
.newAuthTypeResponse()
.setAuthType(AuthTypes.NONE)
.build();
}
function getConfig(request) {
var config = cc.getConfig();
config.newInfo()
.setId('instructions')
.setText('Enter api url to get data , api token , username and password');
config.newTextInput()
.setId('api_url')
.setName('Enter a api url')
.setPlaceholder('https://');
config.newTextInput()
.setId('api_key')
.setName('Enter a Api Key')
.setHelpText('e.g. xxxxxxxxxxxxxxxxx');
config.newTextInput()
.setId('username')
.setName('Enter a username');
config.newTextInput()
.setId('password')
.setName('Enter a username')
.setType('password');
return config.build();
}
function getFields(request) {
var cc = DataStudioApp.createCommunityConnector();
var fields = cc.getFields();
var types = cc.FieldType;
var aggregations = cc.AggregationType;
fields.newDimension()
.setId('username')
.setType(types.TEXT);
fields.newMetric()
.setId('version')
.setType(types.NUMBER);
fields.newDimension()
.setId('address')
.setType(types.TEXT);
return fields;
}
function getSchema(request) {
var fields = getFields(request).build();
return { schema: fields };
}
function responseToRows(requestedFields, response) {
// Transform parsed data and filter for requested fields
return response.map(function(data) {
var row = [];
requestedFields.asArray().forEach(function (field) {
switch (field.getId()) {
case 'username':
return row.push(data.result.user.createdByName);
case 'version':
return row.push(data.result.user.version);
case 'address':
return row.push(data.result.user.address);
default:
return row.push('');
}
});
return { values: row };
});
}
function getData(request) {
var requestedFieldIds = request.fields.map(function(field) {
return field.name;
});
var requestedFields = getFields().forIds(requestedFieldIds);
// Fetch and parse data from API
const API_KEY = request.configParams.api_key;
var url = request.configParams.api_url;
var options = {
'method' : 'post',
'contentType': 'application/json',
"headers":{ "api-key": API_KEY },
"payload": "{username:\""+request.configParams.username+"\", password: \""+request.configParams.password+"\"}",
'muteHttpExceptions': true
};
var response = UrlFetchApp.fetch(url, options);
var parsedResponse = JSON.parse(response);
var rows = responseToRows(requestedFields, parsedResponse);
return {
schema: requestedFields.build(),
rows: rows
};
}
data from api in postman.
{
"result": {
"user": {
"type": "User",
"id": 1073787385,
"address": null,
"version": 1675221634311192576,
"createdBy": 310055,
"createdByName": "Jeirick Hiponia",
}
}
}
In the Apps Script development environment, Clicked on Deploy > Test deployments to open the Test deployments dialog.
To load your connector in Looker Studio, replace the <HEAD_DEPLOYMENT_ID> placeholder in the following link with your connector's Head Deployment ID and follow the link in your browser:
what is the issue?

Calling yahoofinanceapi API

How to convert the below JAVA code to apps script?
I want the quote to be pulled into my sheet
Ticker symbol is in A2
I want the price in B2
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://rest.yahoofinanceapi.com/v6/finance/quote/AAPL"))
.header("x-api-key", "YOUR-PERSONAL-API-KEY")
.method("GET", HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
try the following script
const YOUR_PERSONAL_API_KEY = '... Your API KEY ...';
function fetch_yfapi(ticker_symbol){
let urlToFetch = `https://yfapi.net/v6/finance/quote?region=US&lang=en&symbols=${ticker_symbol}`,
options = {
method: 'get',
headers: {
'accept' : 'application/json',
'X-API-KEY' : YOUR_PERSONAL_API_KEY, },
muteHttpExceptions: true
},
fetched = {
code: null,
body: null,
}
try{
const response = UrlFetchApp.fetch(urlToFetch, options);
fetched.code = response.getResponseCode();
fetched.body = response.getContentText();
if (fetched.code !== 200) {
console.log(Utilities.formatString("Request failed. Expected 200, got %d: %s", fetched.code, fetched.body))
}
} catch(e) {
console.log('Method call error UrlFetchApp.fetch : %s',e)
}
return fetched.body
}
function getTickerData(){
let sheet = SpreadsheetApp.getActive().getSheetByName('... sheet name ...'),
ticker_symbol = sheet.getRange('A2').getValue();
if (ticker_symbol.length) {
let ticker_data = fetch_yfapi(ticker_symbol);
if (ticker_data) {
console.log(ticker_data);
sheet.getRange('B2').setValue(JSON.parse(ticker_data).quoteResponse.result[0].ask)
}
}
}
I didn't know exactly what price you wanted to get in the end - so I put 'ask'. In the console you can see the whole body of the returned response

Google Document Viewer shows: the server cannot process the request because it is malformed

I try to preview the documents on my site using Google viewer. Document url I get from blob, but when I click to show docs I had an error.
In console I see this link: blob:http://localhost:8080/5372d78d-a9c6-4c50-b23b-249cc643bdd2
const url = window.URL.createObjectURL(
new Blob([response.data], { type: response.data.type })
);
const link = document.createElement("iframe");
console.log(url);
link.src = `https://docs.google.com/viewer?url=${url}&embedded=true`;
link.style.width = "100%";
link.style.height = "500px";
document.getElementById(fileId).appendChild(link);
},```
```async showDoc(file) {
this.fileId = file.Document.Id;
this.fileName = file.Document.Name;
try {
let response = await axios.get(url, {
responseType: "blob",
params: {
fileId: this.fileId,
},
});
this.forceFileShow(response, this.fileId);
console.log("удача", response);
} catch (err) {
console.log("неудача", err.response);
}
}
},
And here html:
<div class="card-icon" #click="showDoc(file)"
:data-target="`#showDoc${file.Document.Id}`"
data-toggle="modal">```
[1]: https://i.stack.imgur.com/tZlkm.png

Google Data Studio Community Connector getData() not working as expected

function getData(request){
try{
var options = {
'method' : 'post',
'contentType': 'application/json',
'payload' : JSON.stringify(request)
};
response=UrlFetchApp.fetch(getDataUrl, options);
resData = JSON.parse(response.getContentText())
return resData
}catch (e) {
e = (typeof e === 'string') ? new Error(e) : e;
Logger.log("Catch", e);
throw e;
}
}
The the above is my getData() function.
My isAdminUser() returns true.
When I try to visualize my data, I get the following error
Data Set Configuration Error
Data Studio cannot connect to your data set.
There was an error requesting data from the community connector. Please report the issue to the provider of this community connector if this issue persists.
Error ID: 3d11b88b
https://i.stack.imgur.com/x3Hki.png
The error code changes every time I refresh data and I can't find any dictionary to map the error id to an error
I tried debugging by logging the request parameter, response.getContentText() and resData variable to make sure I my data is formatted correctly.
Following are the logs printed in Stackdriver logs
request
{configParams={/Personal config data/}, fields=[{name=LASTNAME}]}
response.getContentText()
{"schema":[{"name":"LASTNAME","dataType":"STRING"}],"rows":[{"values":["test"]},{"values":["test"]},{"values":["Dummy"]},{"values":["One"]},{"values":["Nagargoje"]},{"values":[""]},{"values":[""]},{"values":[""]},{"values":[""]},{"values":[""]}],"filtersApplied":false}
resData
{rows=[{values=[test]}, {values=[test]}, {values=[Dummy]},
{values=[One]}, {values=[Nagargoje]}, {values=[]}, {values=[]},
{values=[]}, {values=[]}, {values=[]}], filtersApplied=false,
schema=[{name=LASTNAME, dataType=STRING}]}
I am not sure what is wrong with my getData() function.
The Object that I am returning seems to match the structure given here https://developers.google.com/datastudio/connector/reference#getdata
So there was no issue with my getData() function, the issue existed in the manifest file.
I was searching about passing parameter via URL and I stumbled upon a field called
dataStudio.useQueryConfig and added that to my manifest file and set its value to true.
Google Data studio was expecting me to return a query Config for getData().
But what I really wanted was this.
Anyways, I was able to debug it thanks to Matthias for suggesting me to take a look at Open-Source implementations
I implemented JSON connect which worked fine, so I Logged what it was returning in getData() and used that format/structure in my code, but my connector still didn't work.
My next assumption was maybe there is something wrong with my getSchema() return value. So I logged that as well and then copy pasted the hard coded value of both getData() and getSchema() return varaibles from JSON connect.
And even that didn't work, so my last bet was there must be something wrong with the manifest file, maybe the dummy links I added in it must be the issue. Then, after carrying out field by comparison I was finally able to get my community connector working.
This would have been easier to debug if the error messages were a bit helpful and didn't seem so generic.
First: You can always check out the Open-Source implementations that others did for custom Google Data Studio connectors. They are a great source if information. Fore more information checkout the documentation on Open Source Community Connectors.
Second: My implementation is for a time tracking system thus having confidential GDPR relevant data. That's why I can not just give you response messages. But I assembled this code. It contains authentifiction, HTTP GET data fetch and data conversions. Explanation is below the code. Again, checkout the open-source connectors if you need further assistance.
var cc = DataStudioApp.createCommunityConnector();
const URL_DATA = 'https://www.myverysecretdomain.com/api';
const URL_PING = 'https://www.myverysecretdomain.com/ping';
const AUTH_USER = 'auth.user'
const AUTH_KEY = 'auth.key';
const JSON_TAG = 'user';
String.prototype.format = function() {
// https://coderwall.com/p/flonoa/simple-string-format-in-javascript
a = this;
for (k in arguments) {
a = a.replace("{" + k + "}", arguments[k])
}
return a
}
function httpGet(user, token, url, params) {
try {
// this depends on the URL you are connecting to
var headers = {
'ApiUser': user,
'ApiToken': token,
'User-Agent': 'my super freaky Google Data Studio connector'
};
var options = {
headers: headers
};
if (params && Object.keys(params).length > 0) {
var params_ = [];
for (const [key, value] of Object.entries(params)) {
var value_ = value;
if (Array.isArray(value))
value_ = value.join(',');
params_.push('{0}={1}'.format(key, encodeURIComponent(value_)))
}
var query = params_.join('&');
url = '{0}?{1}'.format(url, query);
}
var response = UrlFetchApp.fetch(url, options);
return {
code: response.getResponseCode(),
json: JSON.parse(response.getContentText())
}
} catch (e) {
throwConnectorError(e);
}
}
function getCredentials() {
var userProperties = PropertiesService.getUserProperties();
return {
username: userProperties.getProperty(AUTH_USER),
token: userProperties.getProperty(AUTH_KEY)
}
}
function validateCredentials(user, token) {
if (!user || !token)
return false;
var response = httpGet(user, token, URL_PING);
if (response.code == 200)
console.log('API key for the user %s successfully validated', user);
else
console.error('API key for the user %s is invalid. Code: %s', user, response.code);
return response;
}
function getAuthType() {
var cc = DataStudioApp.createCommunityConnector();
return cc.newAuthTypeResponse()
.setAuthType(cc.AuthType.USER_TOKEN)
.setHelpUrl('https://www.myverysecretdomain.com/index.html#authentication')
.build();
}
function resetAuth() {
var userProperties = PropertiesService.getUserProperties();
userProperties.deleteProperty(AUTH_USER);
userProperties.deleteProperty(AUTH_KEY);
console.info('Credentials have been reset.');
}
function isAuthValid() {
var credentials = getCredentials()
if (credentials == null) {
console.info('No credentials found.');
return false;
}
var response = validateCredentials(credentials.username, credentials.token);
return (response != null && response.code == 200);
}
function setCredentials(request) {
var credentials = request.userToken;
var response = validateCredentials(credentials.username, credentials.token);
if (response == null || response.code != 200) return { errorCode: 'INVALID_CREDENTIALS' };
var userProperties = PropertiesService.getUserProperties();
userProperties.setProperty(AUTH_USER, credentials.username);
userProperties.setProperty(AUTH_KEY, credentials.token);
console.info('Credentials have been stored');
return {
errorCode: 'NONE'
};
}
function throwConnectorError(text) {
DataStudioApp.createCommunityConnector()
.newUserError()
.setDebugText(text)
.setText(text)
.throwException();
}
function getConfig(request) {
// ToDo: handle request.languageCode for different languages being displayed
console.log(request)
var params = request.configParams;
var config = cc.getConfig();
// ToDo: add your config if necessary
config.setDateRangeRequired(true);
return config.build();
}
function getDimensions() {
var types = cc.FieldType;
return [
{
id:'id',
name:'ID',
type:types.NUMBER
},
{
id:'name',
name:'Name',
isDefault:true,
type:types.TEXT
},
{
id:'email',
name:'Email',
type:types.TEXT
}
];
}
function getMetrics() {
return [];
}
function getFields(request) {
Logger.log(request)
var fields = cc.getFields();
var dimensions = this.getDimensions();
var metrics = this.getMetrics();
dimensions.forEach(dimension => fields.newDimension().setId(dimension.id).setName(dimension.name).setType(dimension.type));
metrics.forEach(metric => fields.newMetric().setId(metric.id).setName(metric.name).setType(metric.type).setAggregation(metric.aggregations));
var defaultDimension = dimensions.find(field => field.hasOwnProperty('isDefault') && field.isDefault == true);
var defaultMetric = metrics.find(field => field.hasOwnProperty('isDefault') && field.isDefault == true);
if (defaultDimension)
fields.setDefaultDimension(defaultDimension.id);
if (defaultMetric)
fields.setDefaultMetric(defaultMetric.id);
return fields;
}
function getSchema(request) {
var fields = getFields(request).build();
return { schema: fields };
}
function convertValue(value, id) {
// ToDo: add special conversion if necessary
switch(id) {
default:
// value will be converted automatically
return value[id];
}
}
function entriesToDicts(schema, data, converter, tag) {
return data.map(function(element) {
var entry = element[tag];
var row = {};
schema.forEach(function(field) {
// field has same name in connector and original data source
var id = field.id;
var value = converter(entry, id);
// use UI field ID
row[field.id] = value;
});
return row;
});
}
function dictsToRows(requestedFields, rows) {
return rows.reduce((result, row) => ([...result, {'values': requestedFields.reduce((values, field) => ([...values, row[field]]), [])}]), []);
}
function getParams (request) {
var schema = this.getSchema();
var params;
if (request) {
params = {};
// ToDo: handle pagination={startRow=1.0, rowCount=100.0}
} else {
// preview only
params = {
limit: 20
}
}
return params;
}
function getData(request) {
Logger.log(request)
var credentials = getCredentials()
var schema = getSchema();
var params = getParams(request);
var requestedFields; // fields structured as I want them (see above)
var requestedSchema; // fields structured as Google expects them
if (request) {
// make sure the ordering of the requested fields is kept correct in the resulting data
requestedFields = request.fields.filter(field => !field.forFilterOnly).map(field => field.name);
requestedSchema = getFields(request).forIds(requestedFields);
} else {
// use all fields from schema
requestedFields = schema.map(field => field.id);
requestedSchema = api.getFields(request);
}
var filterPresent = request && request.dimensionsFilters;
//var filter = ...
if (filterPresent) {
// ToDo: apply request filters on API level (before the API call) to minimize data retrieval from API (number of rows) and increase speed
// see https://developers.google.com/datastudio/connector/filters
// filter = ... // initialize filter
// filter.preFilter(params); // low-level API filtering if possible
}
// get HTTP response; e.g. check for HTTT RETURN CODE on response.code if necessary
var response = httpGet(credentials.username, credentials.token, URL_DATA, params);
// get JSON data from HTTP response
var data = response.json;
// convert the full dataset including all fields (the full schema). non-requested fields will be filtered later on
var rows = entriesToDicts(schema, data, convertValue, JSON_TAG);
// match rows against filter (high-level filtering)
//if (filter)
// rows = rows.filter(row => filter.match(row) == true);
// remove non-requested fields
var result = dictsToRows(requestedFields, rows);
console.log('{0} rows received'.format(result.length));
//console.log(result);
return {
schema: requestedSchema.build(),
rows: result,
filtersApplied: filter ? true : false
};
}
A sample request that filters for all users with names starting with J.
{
configParams={},
dateRange={
endDate=2020-05-14,
startDate=2020-04-17
},
fields=[
{name=name}
],
scriptParams={
lastRefresh=1589543208040
},
dimensionsFilters=[
[
{
values=[^J.*],
operator=REGEXP_EXACT_MATCH,
type=INCLUDE,
fieldName=name
}
]
]
}
The JSON data returned by the HTTP GET contains all fields (full schema).
[ { user:
{ id: 1,
name: 'Jane Doe',
email: 'jane#doe.com' } },
{ user:
{ id: 2,
name: 'John Doe',
email: 'john#doe.com' } }
]
Once the data is filtered and converted/transformed, you'll get this result, which is perfectly displayed by Google Data Studio:
{
filtersApplied=true,
schema=[
{
isDefault=true,
semantics={
semanticType=TEXT,
conceptType=DIMENSION
},
label=Name,
name=name,
dataType=STRING
}
],
rows=[
{values=[Jane Doe]},
{values=[John Doe]}
]
}
getData should return data for only the requested fields. In request.fields should have the list of all requested fields. Limit your data for those fields only and then send the parsed data back.

How to import json file into indexeddb?

I am doing an app that store some data in the IndexedDB, but I want to load first some data that is in my json file.
Here is my json file:
{
"ciudades":[
{
"ciudad":"Asuncion",
"latitud":-25.2985296,
"longitud":-57.6710677
},
{
"ciudad":"Caaguazu",
"latitud":-25.465034,
"longitud":-56.0183859
},
{
"ciudad":"Ciudad del Este",
"latitud":-25.4933441,
"longitud":-54.6710438
},
{
"ciudad":"San Pedro",
"latitud":-24.1586759,
"longitud":-56.636503
},
{
"ciudad":"Pedro Juan Caballero",
"latitud":-22.5450875,
"longitud":-55.7618963
}
]
}
you follow step
step 1 read mozilla site
step 2 create indexedDB
var ciudades = [
{
"ciudad":"Asuncion",
"latitud":-25.2985296,
"longitud":-57.6710677
},
{
"ciudad":"Caaguazu",
"latitud":-25.465034,
"longitud":-56.0183859
},
{
"ciudad":"Ciudad del Este",
"latitud":-25.4933441,
"longitud":-54.6710438
},
{
"ciudad":"San Pedro",
"latitud":-24.1586759,
"longitud":-56.636503
},
{
"ciudad":"Pedro Juan Caballero",
"latitud":-22.5450875,
"longitud":-55.7618963
}
];
var IDBSetting = {
name: "indexedDBName",
version: 1,
tables: [{
tableName: "ciudades",
keyPath: "seq",
autoIncrement: true,
index: ["ciudad", "latitud", "longitud],
unique: [false, false, false]
}]
};
! function() {
console.log("indexeDB init");
var req = indexedDB.open(IDBSetting.name, IDBSetting.version);
req.onsuccess = function(event) {
console.log("indexedDB open success");
};
req.onerror = function(event) {
console.log("indexed DB open fail");
};
//callback run init or versionUp
req.onupgradeneeded = function(event) {
console.log("init onupgradeneeded indexedDB ");
var db = event.target.result;
for (var i in IDBSetting.tables) {
var OS = db.createObjectStore(IDBSetting.tables[i].tableName, {
keyPath: IDBSetting.tables[i].keyPath,
autoIncrement: IDBSetting.tables[i].autoIncrement
});
for (var j in IDBSetting.tables[i].index) {
OS.createIndex(IDBSetting.tables[i].index[j], IDBSetting.tables[i].index[j], {
unique: IDBSetting.tables[i].unique[j]
});
}
}
}
}();
step 3 addData
var IDBFuncSet = {
//write
addData: function(table, data) {
var req = indexedDB.open(IDBSetting.name, IDBSetting.version);
req.onsuccess = function(event) {
try {
console.log("addData indexedDB open success");
var db = req.result;
var transaction = db.transaction([table], "readwrite");
var objectStore = transaction.objectStore(table);
var objectStoreRequest = objectStore.add(data);
} catch (e) {
console.log("addDataFunction table or data null error");
console.log(e);
}
objectStoreRequest.onsuccess = function(event) {
//console.log("Call data Insert success");
}
objectStoreRequest.onerror = function(event) {
console.log("addData error");
}
};
req.onerror = function(event) {
console.log("addData indexed DB open fail");
};
}
}
for(var i in ciudades){
IDBFuncSet.addData("ciudades",ciudades[i]);
}
step 4 getData
IDBFuncSet.getAllData = function(arr, table) {
try {
var req = indexedDB.open(IDBSetting.name, IDBSetting.version);
req.onsuccess = function(event) {
var db = req.result;
var transaction = db.transaction([table], "readonly");
var objectStore = transaction.objectStore(table);
var objectStoreRequest = objectStore.openCursor();
objectStoreRequest.onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
arr.push(cursor.value);
cursor.continue();
} else {
}
}
};
req.onerror = function(event) {
console.log("getAllData indexed DB open fail");
};
} catch (e) {
console.log(e);
}
}
var ciudadesArr = [];
IDBFuncSet.getAllData(ciudadesArr, "ciudades");
console.log(ciudadesArr);
I hope this helps
Here's how I've done mine, thanks to the android-indexeddb package.
angular.module('yourApp', ['indexedDB'])
.config(function($indexedDBProvider) {
$indexedDBProvider
.connection('dbName')
.upgradeDatabase(1, function(event, db, tx) {
var objStore = db.createObjectStore('storeOne', { keyPath: 'stop_id' });
objStore.createIndex('store_id', 'store_id', { unique: false });
})
// the next upgradeDatabase() function is necessary if you
// wish to create another datastore
.upgradeDatabase(2, function(event, db, tx) {
var secondObjectStore = db.createObjectStore('storeTwo', { keyPath: 'my_id' });
secondObjectStore.createIndex('another_id', 'another_id', { unique: false });
});
})
Then in my controller:
angular.module('yourApp')
.controller('homeCtrl', ['$scope', '$http', '$indexedDB', function($scope, $http, $indexedDB) {
$scope.objects = [];
var loadJSON = function(file_name) { ... //load the json file in here}
$indexedDB.openStore('storeOne', function(store) {
var loaded = loadJSON('file_name.json');
store.upsert(loaded).then(function(e) {
console.log('added successfully');
});
});
$indexedDB.openStore('times', function(store) {
var loaded = loadJSON('file_name.json');
store.upsert(loaded).then(function(e) {
console.log('added successfully');
});
});
}]);
Check out the project page to learn more of the tricks up this package's sleeves.
Although this angular-indexeddb page supports queries, for advanced queries like joins, you might wanna consider ydn-db
Getting some pretty nice workflow with both packages.
For the loadJSON() function, it could be something like this:
var loadJSON = function(file_name) {
var data;
$.ajax({
url: '../data/' + file_name,
dataType: 'json',
async: false,
success: function(res_data) {
data = res_data;
console.log('Loaded ' + file_name + ' nicely');
},
error: function(err) {
console.log('error happened');
}
});
return data;
}
There is File API, but that doesn't seem to be a solid standard yet.
What I do at the moment, is have the user open the file, copy it's contents to Clipboard, and paste it into a TextArea element on my web page.
In JavaScript I add a listener to the TextArea's change event and parse the text content into JSON, which is then written to indexedDB.