How to retrieve the data from database using Indexed DB - html

I have an existed database. I'm trying to retrieve the data from database using indexedDB but i'm unable to get the data from database.
var data = [];
// creating or opening the database
var db;
var request = window.indexedDB.open("database");
request.onerror = function(event) {
console.log("error: ");
};
request.onsuccess = function(event) {
db = request.result;
console.log("success: "+ db);
};
request.onupgradeneeded = function(event) {
var db = event.target.result;
var objectStore = db.createObjectStore("Subject", {keyPath: "id"});
for (var i in data) {
objectStore.add(data[i]);
}
}
function readAll() {
var objectStore = db.transaction("Subject").objectStore("Subject");
console.log(objectStore);
objectStore.openCursor().onsuccess = function(event) {
var cursor = event.target.result;
if (cursor) {
alert("Name for id " + cursor.key + " is " + cursor.value.Subject);
cursor.continue();
}
else {
alert("No more entries!");
}
};
}
Thanks in Advance.

You're pretty close.
var data = [];
I'll presume that you actually have some data somewhere, and that it indeed has an id attribute since you're specifying that as your index key e.g.
var data = [{id: 'foo' }, { id: 'bar' } ];
Now here:
var objectStore = db.createObjectStore("Subject", {keyPath: "id"});
for (var i in data) {
objectStore.add(data[i]);
}
(Careful with for..in and arrays)
I don't think you're actually adding any data here, which is one reason why you can't read it. To add data to an object store, try to first create a read/write transaction first and then get your reference to the object store and add your object.
var trans = db.transaction(["Subject"], "readwrite").objectStore("Subject");
Note the usage of an array as the first argument to transaction() and "readwrite" as the second param. (Some examples use the IDBTransaction.READ_WRITE constant but this doesn't seem to work with recent versions of Webkit.)
var objectStore = db.transaction("Subject").objectStore("Subject");
Try this instead:
var trans = db.transaction( [ "Subject" ] );
, objectStore = trans.objectStore( "Subject" );
objectStore.openCursor( IDBKeyRange.lowerBound(0) ).onsuccess = function(event) {..}

I did encountered the same error once. it occurs because at times the onSuccess is executed even before the result data is returned. So you should check if result data is empty.
To solve the issue try using oncomplete instead of onSuccess and also use Jquery indexedDB plugin. The plugin requires certin code changes but has more consistent implementation of indexedDB.
See http://nparashuram.com/jquery-indexeddb/

Related

How to build dynamic dropdowns in configuration setup?

I'm new to Google Data Studio and looking into building a community connector for our Saas service.
For the configuration section, I need to use the Stepped Configuration process. Basically, I nested set of drop-down lists.
However, I need the data to populate those lists to come from my API. I have the REST service endpoints defined, but I cannot find any documenation/examples of how I'd configure this in the getConfig section of the community connector.
Does anyone have a working example I could use as reference?
In reviewing the documentation, there is a section on stepped configurations, which is what I am looking for. You can find that example here: https://developers.google.com/datastudio/connector/stepped-configuration#dynamic_dropdowns
In this example, they show the following for defining the dropdown values.
Notice for the states, they have hard-coded the values for "Illinois" and "California".
My question is, how can I dynamically call API to retrieve values to populate this list? I have 3 nested dropdowns, each with a separate API call, using the answer from previous dropdown to drive the next.
For example first API might be http://myapi.com/countries which returns list of countries.
When they select country, next API call might be http://myapi.com/states?country=US
etc.
config.newSelectSingle()
.setId("state")
.setName("State")
// Set isDynamic to true so any changes to State will clear the city
// selections.
.setIsDynamic(true)
.addOption(config.newOptionBuilder().setLabel("Illinois").setValue("IL"))
.addOption(config.newOptionBuilder().setLabel("California").setValue("CA"));
if (!isFirstRequest) {
var city = config.newSelectSingle()
.setId("city")
.setName("City");
var cityOptions = optionsForState(configParams.state);
cityOptions.forEach(function(labelAndValue) {
var cityLabel = labelAndValue[0];
var cityValue = labelAndValue[1];
city.addOption(config.newOptionBuilder().setLabel(cityLabel).setValue(cityValue));
});
}
return config.build();
}
Worked through the issues I was having. For others who might have hit similiar issues, here's my working getConfig() method.
function getConfig(request) {
var config = cc.getConfig();
var configParams = request.configParams;
var isFirstRequest = configParams === undefined;
if (configParams ===undefined || configParams.tab ===undefined) {
config.setIsSteppedConfig(true);
}
var url ='https://<yourAPIURL>';
var userProperties = PropertiesService.getUserProperties();
var key = userProperties.getProperty('dscc.key');
var mykey ="Bearer " + key
var options = {
"method" : "GET",
"headers" : {
"AUTHORIZATION" : mykey,
"cache-control": "no-cache"
}
};
var response = UrlFetchApp.fetch(url,options);
var parsedResponse = JSON.parse(response);
var zoneControl = config.newSelectSingle()
.setId("zone")
.setName("Zone")
.setIsDynamic(true);
parsedResponse.map(function(itm) {
zoneControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.id))
});
if(configParams !==undefined && configParams.zone !==undefined){
var blockurl ='https://<yourAPIURL>?zoneid='+ configParams.zone;
var blockResponse = UrlFetchApp.fetch(blockurl,options);
var parsedBlockResponse = JSON.parse(blockResponse);
var blockControl = config.newSelectSingle()
.setId("block")
.setName("Block")
.setIsDynamic(true);
parsedBlockResponse.map(function(itm) {
blockControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.blockKey))
});
}
if(configParams !==undefined && configParams.block !==undefined){
var taburl =''https://<yourAPIURL>?blockKey='+ configParams.block;
var tabResponse = UrlFetchApp.fetch(taburl,options);
var parsedTabResponse = JSON.parse(tabResponse);
var tabControl = config.newSelectSingle()
.setId("tab")
.setName("Tab")
parsedTabResponse.map(function(itm) {
tabControl.addOption(config.newOptionBuilder().setLabel(itm.name).setValue(itm.internalname))
});
}
return config.build();
}
without testing the code:
function getConfig(request) {
var configParams = request.configParams;
var isFirstRequest = configParams === undefined;
var lst=["A","B","C"]; // your values obtained from REST
var tmp=config.newSelectSingle(); //add element to side
var element=tmp.setId("state").setName("State").setIsDynamic(true); // set name and id
for(var i in lst) // set all the values:
{
element = element.addOption(config.newOptionBuilder().setLabel(lst[i]).setValue(lst[i]))
}
if(isFirstRequest || configParams.state==undefined) // no state selected yet
{
config.setIsSteppedConfig(true); // stop here
}
else
{
// next dropdown element,
// Rest API with element set to: configParams.state
var lst2= ["x","y","z"]
var tmp2=config.newSelectSingle(); //add element to side
var element2=tmp2.setId("element2").setName("Element 2 depends on "+configParams.state).setIsDynamic(true); // set name and id
for(var i in lst2) // set all the values:
{
element2 = element2.addOption(config.newOptionBuilder().setLabel(lst2[i]).setValue(lst2[i]))
}
// code for 3rd
}
}
If the user changes the first dropdown value alle other drop downs have to be reset. This may be a bit tricky.

How to update objects using Cloud Code?

I am using Parse Cloud Code for retrieving JSON data from external API. JSON data are updated every 2 min.
To accomplish this, I am using Cloud Job to run my method every 2 minutes to keep data fresh. Also, I am storing whole JSON data to Parse.
When I run this code for the first time everything works well, but... when code runs for second, third or fourth time instead of updating objects it creates the new ones.
How to update objects instead of creating the new ones, when there are some data?
Code:
Parse.Cloud.define("getCars", function(request, response) {
var promise = new Parse.Promise();
var Cars = Parse.Object.extend('Cars');
var query = new Parse.Query(Cars);
query.find().then(function (results){
Parse.Cloud.httpRequest({
method: 'GET',
url: urlLink,
success: function(httpResponse) {
var stations = new Array();
var data = JSON.parse(decodeURIComponent(escape(httpResponse.text))); // utf-8 decode
for (var i = 0; i < data.length; i++) {
var Cars = Parse.Object.extend('Cars'),
car = new Cars(),
content = data[i];
car.set('number', content.number);
car.set('name', content.name);
car.set('address', content.address);
car.set('position', content.position);
car.set('status', content.status);
cars.push(station);
};
Parse.Object.saveAll(cars, {
success: function(objects) {
promise.resolve();
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
promise.reject(error.message);
}
});
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
promise.reject(error.message);
}
});
});
return promise;
});
SOLUTION
I have finally found the solution. Maybe this will be useful for other people who are facing the same problem.
I added a simple if statement which checks query result. If query does not return data, new object is created, otherwise: old object is filled with new information and saved into database.
station = (results == 0) ? new Stations() : results[i];
you are createting new object car = new Cars(), every time.instead find with objectId and in success response you will get ParseObject list(array).
update first parseObject from that list

SAPUI5 get single property from JSON-Model

I am currently trying to figure out how I can retrieve a single value from a sap.ui.model.json.JSONModel
in my main view:
var gConfigModel = new sap.ui.model.json.JSONModel();
var getConfigCallback = function(config) {
gConfigModel.setData(config);
};
oController.getConfiguration(getConfigCallback);
console.log(gConfigModel);
in my controller:
getConfiguration : function(callback) {
var sServiceUrl = "/sap/opu/odata/sap/xxx/ConfigurationSet('Initialize')";
var config = {};
callback(config);
$.getJSON(sServiceUrl).done(function(data) {
config = data.d;
callback(config);
});
},
In my console.log statement I can see that the data was successfully passed from the backend and successfully set to the JSON model. My requirement is to store the value of attribute Editable in a single variable.
I already tried gConfigModel.getProperty('/'), didnt work. tried to access gConfigModel.oData was undefined .. How can I store it in a single value?
Solution Comment: If you catch data from a backend, you have to take care how long it takes. data can be available later then expected, in my case I added 1s timeout, afterwards I can access the property easily
setTimeout(function() {
console.log(gConfigModel.getProperty('/Editable'));
}, 1000);
I wouldn't advise using the model's getData() method since it is deprecated.
A much better solution is to use gConfigModel.getProperty("/Editable")
(I'm using the root slash here since your property resides in the root of your model)
In the same way, you can also set your data:
gConfigModel.setProperty("/Editable", <your new value>) instead
First of all, thanks for the effort to find solutions of our Problems! (at least, those regarding It stuff.. :) )
I've found a solution which I think is a little bit more save because the timeout is maybe somewhat arbitrary - it would depend on the machine or the amount of data that is to be fetched?
Therefore, I am using an attachRequestCompleted function:
with sUrl_2="path-to-my-service";
var oModel_2 = new sap.ui.model.json.JSONModel(sUrl_2);
oModel_2.attachRequestCompleted(function(data) {
//now, i can access the data stored in the oModel_2, either by getProperty, or by DOM: oModel_2.oData.d.Vendor
gv_selLieferant = oModel_2.getProperty("/d/Vendor");
gv_selEinkOrg = oModel_2.getProperty("/d/PurchOrg");
gv_selEinKGru = oModel_2.getProperty("/d/PurGroup");
});
<script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js" id="sap-ui-bootstrap" data-sap-ui-theme="sap_bluecrystal" data-sap-ui-libs="sap.m"></script>
<script>
function getConfiguration(callback) {
var sServiceUrl = "/sap/opu/odata/sap/xxx/ConfigurationSet('Initialize')";
var config = {};
var data = {
"d": {
"_metadata": "",
"Backup01": "01",
"Editable": "True"
}
};
setTimeout((function() {
config = data;
callback(config);
})(), 2000);
};
var gConfigModel = new sap.ui.model.json.JSONModel();
var getConfigCallback = function(config) {
gConfigModel.setData(config);
alert(gConfigModel.getProperty("/d/Editable"));
};
getConfiguration(getConfigCallback);
</script>

How to create an object of specific type from JSON in Parse

I have a Cloud Code script that pulls some JSON from a service. That JSON includes an array of objects. I want to save those to Parse, but using a specific Parse class. How can I do it?
Here's my code.
Parse.Cloud.httpRequest({
url: 'http://myservicehost.com',
headers: {
'Authorization': 'XXX'
},
success: function(httpResponse) {
console.log("Success!");
var json = JSON.parse(httpResponse.text);
var recipes = json.results;
for(int i=0; i<recipes.length; i++) {
var Recipe = Parse.Object.extend("Recipe");
var recipeFromJSON = recipes[i];
// how do i save recipeFromJSON into Recipe without setting all the fields one by one?
}
}
});
I think I got it working. You need to set the className property in the JSON data object to your class name. (Found it in the source code) But I did only try this on the client side though.
for(int i=0; i<recipes.length; i++) {
var recipeFromJSON = recipes[i];
recipeFromJSON.className = "Recipe";
var recipeParseObject = Parse.Object.fromJSON(recipeFromJSON);
// do stuff with recipeParseObject
}
Example from this page https://parse.com/docs/js/guide
var GameScore = Parse.Object.extend("GameScore");
var gameScore = new GameScore();
gameScore.save({
score: 1337,
playerName: "Sean Plott",
cheatMode: false
}, {
success: function(gameScore) {
// The object was saved successfully.
},
error: function(gameScore, error) {
// The save failed.
// error is a Parse.Error with an error code and message.
}
});
IHMO this question is not a duplicate of How to use Parse.Object fromJSON? [duplicate]
In this question the JSON has not been generated by the Parse.Object.toJSON function itself, but comes from another service.
const object = new Parse.Object('MyClass')
const asJson = object.toJSON();
// asJson.className = 'MyClass';
Parse.Object.fromJSON(asJson);
// Without L3 this results into:
// Error: Cannot create an object without a className
// It makes no sense (to me) why the Parse.Object.toJSON is not reversible

How to loop through indexedDB tables synchronously?

I want to write a function in JS where I will loop through a tables in my indexed DB and get the maximum value of last modified of table and return that
function readData(){
var trans = '';
trans = idb.transaction(["tableName"],'readonly'); // Create the transaction
var request = trans.objectStore("tableName").openCursor();
request.onsuccess = function(e) {
var cursor = request.result || e.result;
if(cursor) {
// logic to and find maximum
} else {
return // max last modified
}
cursor.continue();
}
}
IMP--Since onsuccess method is asynchronous how can i make it synchronous? so that my method readData() will return only when max last modified record is found successfully. I can call this method(readData()) synchronously to get last modified record of 2-3 tables if I want.
The sync API is only available in a webworker. So this would be the first requirement. (As far as I know only IE10 supports this at the moment)
An other shot you can give is working with JS 1.7 and use the yield keyword. For more information about it look here
I would sugest to work with a callbakck method that you call when you reached the latest value.
function readData(callback){
var trans = '';
trans = idb.transaction(["tableName"],'readonly'); //Create the transaction
var request = trans.objectStore("tableName").openCursor();
var maxKey;
request.onsuccess = function(e) {
var cursor = request.result || e.result;
if(cursor.value){
//logic to and find maximum
maxKey = cursor.primaryKey
cursor.continue();
}
}
trans.oncomplete = function(e) {
callback(maxKey);
}
}
IndexedDB API in top frame is async. async cannot be synchronous. But you can read all tables in single transaction.