Javascript for of loop runs only once - javascript

I'm fetching data form a API and since I have to collect lots of data, I'm using the setTimeOut function to delay the requests by 3s each. But, when I try to run the code, the for loop only run once and finishes the program.
const fs = require('fs')
const { JSDOM } = require("jsdom")
const { window } = new JSDOM("")
const $ = require("jquery")(window)
const path = require('path')
const fetchArt = require('./utils/fetchArt.js')
const { data } = require('jquery')
const { resolve } = require('path')
let replacer = RegExp(' ', 'g')
let slash = RegExp('/', 'g')
const requestArtSongs = (artist) => {
return $.getJSON("https://www.vagalume.com.br/" + artist + "/index.js").then(
function (data) {
return data.artist.lyrics.item
}
)
}
const map = (lang) => {
switch (lang) {
case 1: return 'pt'
case 2: return 'en'
default: return lang
}
}
const requestMusic = (artist, song) => {
return $.getJSON(
"https://api.vagalume.com.br/search.php"
+ "?art=" + artist
+ "&mus=" + song
+ "&apikey={key}"
).then(function (data) {
return [data.mus[0].text, data.mus[0].lang]
})
}
const makeRequest = (art, songs) => {
songs.forEach((song, i) => {
delay(3000 * (i+1))
.then(() => makeSongRequest(art, song.desc))
})
}
const writeFile = (art, songName, mus) => {
gen = gens[0]
let music = {
artist: art,
song: {
name: songName,
text: mus[0],
lang: map(mus[1])
}
}
if (fs.existsSync(path.join(__dirname, 'Genders', gen, art))) {
fs.writeFile(path.join(__dirname, 'Genders', gen, art, `${songName.replace(slash, '')}.json`),
JSON.stringify(music, null, 4),
(err) => {
if (err) throw err
console.log('Song ' + songName + ' written!')
})
} else {
fs.mkdir(path.join(__dirname, 'Genders', gen, art), { recursive: true }, err => {
if (err) throw err
fs.writeFile(path.join(__dirname, 'Genders', gen, art, `${songName.replace(slash, '')}.json`),
JSON.stringify(music, null, 4),
(err) => {
if (err) throw err
console.log('Song ' + songName + ' written!')
})
})
}
}
const makeSongRequest = (art, songName) => {
requestMusic(art, songName)
.then(mus => {
writeFile(art, songName, mus)
})
}
const delay = t => new Promise (resolve => setTimeout(resolve, t))
const writeSongs = (artist) => {
art = artist.replace(replacer, '-').toLowerCase()
return new Promise(() => {
requestArtSongs(art)
.then((songs) => {
makeRequest(artist, songs)
})
})
}
const main = async () => {
let gens = ['Funk']
for (let gen of gens){
let arts = await fetchArt(gen)
for (let art of arts) {
await writeSongs(art)
}
}
}
main()
On my main function, I'm trying to fetch lyrics from the API. For each gender (in this case, only 'Funk') I get the artists that sing that gender. Then, for each artist I run the writeSongs function that does lots of stuff.
I'm using Node JS to do all the work.

Related

How to stop a function called infinitely?

I have this bunch of code which runs infinitely as it can be seen from the terminal img. How can I stop it? Delete function is assigned to a button so I don't know why it runs even though I didn't click that button.
//server.js
app.get("/getMaintenanceTypes",(req,res)=>{
pool.query(`Select * from maintenancetypes`, (err, result) => {
if(!err){
console.log("maintanencetypes", result.rows);
res.status(200).send(result.rows);
}else{
res.status(404).json(err.message)
console.log("maintanencetypes", err.message)
}
})
})
//main.js
const getMainTypes = async () => {
const response = await axios.get(`${serverBaseUrl}/getMaintenanceTypes`);
//console.log("response", response.data);
const response2 = [];
for (var i = 0; i < response.data.length; i++) {
let entry = {
id: null,
title: "",
description: "",
};
entry.id = response.data[i].id;
entry.title = response.data[i].title;
entry.description = response.data[i].description;
response2.push(entry);
//console.log("entry", entry);
}
console.log("RESPONSE2", response2);
return response2;
}
async function deleteAllMainTypes() {
try {
const resp = await axios.delete(
`${serverBaseUrl}/deleteAllMainTypes`
);
} catch (error) {
console.log(error);
}
const maintenanceList = await getMainTypes();
//console.log("main list", maintenanceList);
setMaintenanceList(maintenanceList);
};
const deleteHandler = () => {
deleteAllMainTypes();
}
<Button onClick={deleteHandler} >Delete All</Button>

Return empty array in Fastify handler with async/await function

I'm trying to make a web3 wallet with Moralis with Fasitify in back and VueJS in front.
(I would like to say that I already do this in web client (vuejs) and everything works well!)
In my back, I fetch all the asset from user. It works, I get them all well and I can send them back to the front
But I need to process/sort the data to recover only part of it and send it to the front to avoid doing too much treatment at the front and reduce your workload.
I do that :
*handlers/token.js*
const getTokenBalances = async () => {
let userTokens;
const options = {
chain: "bsc",
address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
};
userTokens = await Moralis.Web3API.account.getTokenBalances(options);
return userTokens;
};
and if I return userTokens, I had it in Postman. But now, I do something like :
const getTokenBalances = async (tokens) => {
let userTokens;
let userBalances = [];
const options = {
chain: "bsc",
address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
};
userTokens = await Moralis.Web3API.account.getTokenBalances(options);
userTokens.forEach((token) => {
if (
!token.name.match(/^.*\.io/) &&
!token.name.match(/^.*\.IO/) &&
!token.name.match(/^.*\.net/) &&
!token.name.match(/^.*\.Net/) &&
!token.name.match(/^.*\.com/) &&
!token.name.match(/^.*\.org/)
) {
getTokenPair(token).then((value) => {
if (value > 2) {
checkTokenPrice(token).then((price) => {
if (price > 0.001) {
userBalances.push(token);
}
});
}
});
}
});
userBalances.sort((a, b) => {
return b.total_value_usd - a.total_value_usd;
});
return userBalances;
};
userBalances its always empty in my response in Postman (And I don't understand why ?)
The getTokenPair function :
const getTokenPair = async (token) => {
const BNBTokenAddress = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c"; //BNB
const options = {
token0_address: token.token_address,
token1_address: BNBTokenAddress,
exchange: "pancakeswapv2",
chain: "bsc",
};
try {
const pairAddress = await Moralis.Web3API.defi.getPairAddress(options);
let amount = 0;
//console.log("token pairAddress : " + pairAddress.pairAddress);
if (pairAddress.token1.symbol === "BUSD") {
try {
let reserve = await getPairReserves(pairAddress.pairAddress);
amount += reserve / 10 ** 18;
} catch (err) {
console.log("error getReservesBUSD : " + err);
}
}
if (pairAddress.token1.symbol === "WBNB") {
try {
let reserve = await getPairReserves(pairAddress.pairAddress);
amount += reserve / 10 ** 18;
} catch (err) {
console.log("error getReservesWBNB : " + err);
}
}
//console.log("amount : " + amount)
return amount;
} catch (err) {
console.log("error getPair : " + err);
}
};
and the checkTokenPrice function :
const checkTokenPrice = async (token) => {
let price;
const options = {
address: token.token_address,
chain: "bsc",
exchange: "PancakeSwapv2",
};
try {
const priceToken = await Moralis.Web3API.token.getTokenPrice(options);
price = priceToken.usdPrice.toFixed(7);
token.price = priceToken.usdPrice.toFixed(7);
token.balance = insertDecimal(token.balance, token.decimals);
token.total_value_usd = (token.balance * token.price).toFixed(2);
return price;
} catch (err) {
console.log("error tokenPrice : " + err);
}
};
They are await method in all the function I use so maybe there is a connection.
Thanks for you help !
**** EDIT *****
I solve my problem like this :
const getTokenBalances = async () => {
let userTokens;
let userBalances = [];
const options = {
chain: "bsc",
address: "0x935A438C29bd810c9aBa2F3Df5144d2dF4F3c0A0",
};
userTokens = await Moralis.Web3API.account.getTokenBalances(options);
for (token of userTokens) {
if (
!token.name.match(/^.*\.io/) &&
!token.name.match(/^.*\.IO/) &&
!token.name.match(/^.*\.net/) &&
!token.name.match(/^.*\.Net/) &&
!token.name.match(/^.*\.com/) &&
!token.name.match(/^.*\.org/)
) {
let value = await getTokenPair(token);
if(value > 2) {
let price = await checkTokenPrice(token);
if (price > 0.001) {
userBalances.push(token);
}
}
}
}
return userBalances;
};
Thanks for the help ! ;)

Gatsby createPages lifecycle method running before onCreateNode method finishes adding needed node fields

I am working on a Gatsby site that uses gatsby-source-wordpress. In my gatbsy-node.js file, I use the onCreateNote lifecycle method to determine if the node is a certain WordPress custom post type, then I reach out to a separate API to get related information for the post type, use createNodeField to add it as a field, and sometimes also use createRemoteFileNode to add images sourced from the API to a field on the new node.
Now this works great most of the time, but occasionally the createPages lifecycle method runs while the image/node code is still happening (I believe). This means that the image fields don't exist yet, and the page creation fails. Then after it fails, I see a console message in the log that I set up where it notifies me that the new field has successfully been added to the node.
How can I make sure that all of those nodes are finished and the data is complete, BEFORE the createPages lifecycle runs? It seems when the client uploads a larger image, this is more likely to fail... which makes sense if I'm understanding this correctly. Here is the code from my gatsby-node.js file:
const path = require(`path`);
const slash = require(`slash`);
const fetch = require('node-fetch');
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)
exports.onCreateNode = ({ node, actions, store, cache,createNodeId, }) => {
const { createNode, createNodeField } = actions;
function getData(url) {
return new Promise((resolve, reject) => {
fetch(url)
.then((response) => response.json())
.then((data) => {
resolve(data);
});
})
}
if( node.internal.type === "wordpress__wp_location"){
const yextID = node.acf.yext_entity_id;
const yextOrthos = node.acf.location_orthodontists;
try {
const getLocation = async () => {
const data = await fetch("https://api.yext.com/v2/accounts/me/entities?api_key=" + process.env.YEXT_API_KEY + "&v=20191114&filter=%7B%22%24anywhere%22%3A%20%22" + yextID + "%22%7D&entityTypes=healthcareFacility")
.then(response => response.json());
// Transform the data into json
if( data && data.response && data.response.count === 1 ){
createNodeField({
node,
name: `yextLocation`,
value: data.response.entities[0]
});
} else {
console.log("NO LOCATIONS FOUND");
}
};
function getOrthos(){
let orthodontists = [];
yextOrthos.forEach( (ortho, i) => {
orthodontists.push(getData("https://api.yext.com/v2/accounts/me/entities?api_key=" + process.env.YEXT_API_KEY + "&v=20191114&filter=%7B%22%24anywhere%22%3A%20%22" + ortho.acf.yext_entity_ortho_id + "%22%7D&entityTypes=healthcareProfessional"));
});
Promise.all(orthodontists).then( (orthoData) => {
if( orthoData.length ){
let finalOrthos = [];
orthoData.forEach( (finalOrtho, x) => {
finalOrthos.push(finalOrtho.response.entities[0]);
});
createNodeField({
node,
name: `yextOrthos`,
value: finalOrthos
});
} else {
console.log("NO DOCTORS FOUND");
}
});
}
getLocation();
getOrthos();
} catch (error) {
console.log(error);
}
}
if( node.internal.type === "wordpress__wp_orthodontist"){
const yextID = node.acf.yext_entity_ortho_id;
const wpID = node.wordpress_id;
try {
const getTextOrtho = async () => {
const data = await fetch("https://api.yext.com/v2/accounts/me/entities?api_key=" + process.env.YEXT_API_KEY + "&v=20191114&filter=%7B%22%24anywhere%22%3A%20%22" + yextID + "%22%7D&entityTypes=healthcareProfessional")
.then(response => response.json());
// Transform the data into json
if( data && data.response && data.response.count === 1 ){
googleProfilePhoto = data.response.entities[0].googleProfilePhoto.url;
createNodeField({
node,
name: `yextOrthodontist`,
value: data.response.entities[0]
});
if( data.response.entities[0].googleProfilePhoto && data.response.entities[0].googleProfilePhoto.url){
createNodeField({
node,
name: `yextProfilePicture`,
value: data.response.entities[0].googleProfilePhoto.url
});
let fileNode = await createRemoteFileNode({
url: data.response.entities[0].googleProfilePhoto.url, // string that points to the URL of the image
parentNodeId: node.id, // id of the parent node of the fileNode you are going to create
createNode, // helper function in gatsby-node to generate the node
createNodeId, // helper function in gatsby-node to generate the node id
cache, // Gatsby's cache
store, // Gatsby's redux store
})
// if the file was created, attach the new node to the parent node
if (fileNode) {
console.log("GOOGLE PROFILE NODE CREATED!")
node.featuredImg___NODE = fileNode.id
} else {
console.log("ERROR! fileNode not Created!");
}
} else {
console.log("NO GOOGLE PROFILE PHOTO FOUND");
}
} else {
console.log("NO ORTHODONTISTS FOUND");
}
}
const getWpLocations = async () => {
const data = await fetch(process.env.GATSBY_WP_BASEURL+ "/wp-json/custom_endpoint/v1/locations_by_orthodontist?orthodontist_id=" + wpID).then(response => response.json());
if( data ){
createNodeField({
node,
name: `wpLocations`,
value: data
});
} else {
console.log("NO ORTHODONTISTS FOUND");
}
}
getTextOrtho();
getWpLocations();
} catch (error) {
console.log(error);
}
}
}
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions;
const result = await graphql(`
{
locations: allWordpressWpLocation(filter: {status: {eq: "publish"}}) {
nodes {
id
path
acf {
location_orthodontists {
acf {
yext_entity_ortho_id
}
}
yext_entity_id
}
}
}
pages: allWordpressPage(
filter: {
wordpress_id: {nin: [177, 183, 8, 42, 44, 185, 46]}
status: {eq: "publish"}
}) {
nodes {
id
wordpress_id
path
}
}
orthodontists: allWordpressWpOrthodontist(filter: {status: {eq: "publish"}}) {
nodes {
id
path
}
}
posts: allWordpressPost(filter: {status: {eq: "publish"}}) {
nodes {
slug
id
}
}
}
`);
// Check for any errors
if (result.errors) {
throw new Error(result.errors);
}
const { locations, pages, orthodontists, posts } = result.data;
const locationTemplate = path.resolve(`./src/templates/location.js`);
const pageTemplate = path.resolve(`./src/templates/page.js`);
const orthoTemplate = path.resolve(`./src/templates/orthodontist.js`);
const postTemplate = path.resolve(`./src/templates/post.js`);
const blogTemplate = path.resolve(`./src/templates/blog.js`);
locations.nodes.forEach(node => {
let orthodontists = [];
node.acf.location_orthodontists.forEach(ortho => {
orthodontists.push(ortho.acf.yext_entity_ortho_id);
});
let orthodontistList = orthodontists.join();
createPage({
path: `${node.path}`,
component: slash(locationTemplate),
context: {
id: node.id,
yextId: node.acf.yext_entity_id,
yextOrthoIds: orthodontists
},
});
});
pages.nodes.forEach(node => {
createPage({
path: `${node.path}`,
component: slash(pageTemplate),
context: {
id: node.id,
},
});
});
orthodontists.nodes.forEach(node => {
createPage({
path: `${node.path}`,
component: slash(orthoTemplate),
context: {
id: node.id,
},
});
});
posts.nodes.forEach(node => {
createPage({
path: `${node.slug}`,
component: slash(postTemplate),
context: {
id: node.id,
},
});
});
const postsPerPage = 12;
const numPages = Math.ceil(posts.nodes.length / postsPerPage);
Array.from({ length: numPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/blog` : `/blog/page/${i + 1}`,
component: slash(blogTemplate),
context: {
limit: postsPerPage,
skip: i * postsPerPage,
numPages,
currentPage: i + 1,
},
})
})
};
Thanks for any information you can provide! I imagine this is probably due to me still learning to use asynchronous behavior in JS, but I just can't seem to find information on how to make this happen.
Please let me know if I can explain the situation any better!
After a rewrite, this seems to have solved the issue I was having. I'll be honest, I'm still working on completely understanding the ins and outs on async/await/promises functionality in JS, but hopefully if someone encounters a similar problem, viewing this rewrite may help:
const path = require(`path`);
const slash = require(`slash`);
const fetch = require('node-fetch');
const { createRemoteFileNode } = require(`gatsby-source-filesystem`)
exports.onCreateNode = async ({ node, actions, store, cache,createNodeId, }) => {
const { createNode, createNodeField } = actions;
const getData = async (url) => {
return new Promise((resolve, reject) => {
fetch(url)
.then((response) => response.json())
.then((data) => {
resolve(data);
});
})
}
const getLocation = async (yextID) => {
const data = await getData("https://api.yext.com/v2/accounts/me/entities?api_key=" + process.env.YEXT_API_KEY + "&v=20191114&filter=%7B%22%24anywhere%22%3A%20%22" + yextID + "%22%7D&entityTypes=healthcareFacility");
// Transform the data into json
if( data && data.response && data.response.count === 1 ){
createNodeField({
node,
name: `yextLocation`,
value: data.response.entities[0]
});
} else {
console.log("NO LOCATIONS FOUND");
}
};
const getOrthos = async (yextOrthos) => {
let orthodontists = [];
yextOrthos.forEach( (ortho, i) => {
orthodontists.push(getData("https://api.yext.com/v2/accounts/me/entities?api_key=" + process.env.YEXT_API_KEY + "&v=20191114&filter=%7B%22%24anywhere%22%3A%20%22" + ortho.acf.yext_entity_ortho_id + "%22%7D&entityTypes=healthcareProfessional"));
});
Promise.all(orthodontists).then( (orthoData) => {
if( orthoData.length ){
let finalOrthos = [];
orthoData.forEach( (finalOrtho, x) => {
finalOrthos.push(finalOrtho.response.entities[0]);
});
createNodeField({
node,
name: `yextOrthos`,
value: finalOrthos
});
} else {
console.log("NO DOCTORS FOUND");
}
});
};
const getTextOrtho = async (yextID) => {
const data = await getData("https://api.yext.com/v2/accounts/me/entities?api_key=" + process.env.YEXT_API_KEY + "&v=20191114&filter=%7B%22%24anywhere%22%3A%20%22" + yextID + "%22%7D&entityTypes=healthcareProfessional");
if( data && data.response && data.response.count === 1 ){
createNodeField({
node,
name: `yextOrthodontist`,
value: data.response.entities[0]
});
if( data.response.entities[0].googleProfilePhoto && data.response.entities[0].googleProfilePhoto.url){
createNodeField({
node,
name: `yextProfilePicture`,
value: data.response.entities[0].googleProfilePhoto.url
});
let fileNode = await createRemoteFileNode({
url: data.response.entities[0].googleProfilePhoto.url, // string that points to the URL of the image
parentNodeId: node.id, // id of the parent node of the fileNode you are going to create
createNode, // helper function in gatsby-node to generate the node
createNodeId, // helper function in gatsby-node to generate the node id
cache, // Gatsby's cache
store, // Gatsby's redux store
});
// if the file was created, attach the new node to the parent node
if (fileNode) {
node.featuredImg___NODE = fileNode.id;
console.log("GOOGLE PROFILE NODE CREATED!")
} else {
console.log("ERROR! fileNode not Created!");
}
} else {
console.log("NO GOOGLE PROFILE PHOTO FOUND");
}
} else {
console.log("NO ORTHODONTISTS FOUND");
}
};
const getWpLocations = async (wpID) => {
const data = await getData(process.env.GATSBY_WP_BASEURL+ "/wp-json/perch_endpoint/v1/locations_by_orthodontist?orthodontist_id=" + wpID);
if( data ){
createNodeField({
node,
name: `wpLocations`,
value: data
});
} else {
console.log("NO ORTHODONTISTS FOUND");
}
}
if( node.internal.type === "wordpress__wp_location"){
const yextID = node.acf.yext_entity_id;
const yextOrthos = node.acf.location_orthodontists;
try {
await getLocation(yextID);
await getOrthos(yextOrthos);
} catch (error) {
console.log(error);
}
}
if( node.internal.type === "wordpress__wp_orthodontist"){
const yextID = node.acf.yext_entity_ortho_id;
const wpID = node.wordpress_id;
try {
await getTextOrtho(yextID);
await getWpLocations(wpID);
} catch (error) {
console.log(error);
}
}
}
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions;
const result = await graphql(`
{
locations: allWordpressWpLocation(filter: {status: {eq: "publish"}}) {
nodes {
id
path
acf {
location_orthodontists {
acf {
yext_entity_ortho_id
}
}
yext_entity_id
}
}
}
pages: allWordpressPage(
filter: {
wordpress_id: {nin: [177, 183, 8, 42, 44, 185, 46]}
status: {eq: "publish"}
}) {
nodes {
id
wordpress_id
path
}
}
orthodontists: allWordpressWpOrthodontist(filter: {status: {eq: "publish"}}) {
nodes {
id
path
}
}
posts: allWordpressPost(filter: {status: {eq: "publish"}}) {
nodes {
slug
id
}
}
}
`);
// Check for any errors
if (result.errors) {
throw new Error(result.errors);
}
const { locations, pages, orthodontists, posts } = result.data;
const locationTemplate = path.resolve(`./src/templates/location.js`);
const pageTemplate = path.resolve(`./src/templates/page.js`);
const orthoTemplate = path.resolve(`./src/templates/orthodontist.js`);
const postTemplate = path.resolve(`./src/templates/post.js`);
const blogTemplate = path.resolve(`./src/templates/blog.js`);
locations.nodes.forEach(node => {
let orthodontists = [];
node.acf.location_orthodontists.forEach(ortho => {
orthodontists.push(ortho.acf.yext_entity_ortho_id);
});
let orthodontistList = orthodontists.join();
createPage({
path: `${node.path}`,
component: slash(locationTemplate),
context: {
id: node.id,
yextId: node.acf.yext_entity_id,
yextOrthoIds: orthodontists
},
});
});
pages.nodes.forEach(node => {
createPage({
path: `${node.path}`,
component: slash(pageTemplate),
context: {
id: node.id,
},
});
});
orthodontists.nodes.forEach(node => {
createPage({
path: `${node.path}`,
component: slash(orthoTemplate),
context: {
id: node.id,
},
});
});
posts.nodes.forEach(node => {
createPage({
path: `${node.slug}`,
component: slash(postTemplate),
context: {
id: node.id,
},
});
});
const postsPerPage = 12;
const numPages = Math.ceil(posts.nodes.length / postsPerPage);
Array.from({ length: numPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/blog` : `/blog/page/${i + 1}`,
component: slash(blogTemplate),
context: {
limit: postsPerPage,
skip: i * postsPerPage,
numPages,
currentPage: i + 1,
},
})
})
};

Asynchronous indexedDB in a class object

I have written a tiny indexedDB library but dosen't seem to work as expected. So my question is how do i fix or properly reconstruct the code bellow to work as expected with a promise. I'm out of idea.
Although the add and delete method works in terms of successfully adding and deleting item from the database but the delete method won't signal it .then function
class IDB {
constructor(name, version) {
this.name = name;
this.version = version;
this.db = null;
}
open(callback) {
const req = window.indexedDB.open(this.name, this.version);
req.onupgradeneeded = (e) => {
let db = e.target.result;
callback(db);
}
req.onsuccess = (e) => {
this.db = e.target.result;
this.db.onversionchange = () => {
this.db.close();
console.log('Tell user to reload the page');
}
}
req.onerror = (e) => {
let db = e.target.errorCode;
return;
}
}
result(req) {
return new Promise((resolve, reject) => {
if (req) {
req.onsuccess = (e) => {
let res = e.target.result;
if (res) {
resolve(res);
}
};
req.onerror = (e) => {
let err = e.target.errorCode;
if (err) {
reject(err);
}
};
}
})
}
add(store, Items) {
let req;
let tx = this.db.transaction([store], 'readwrite').objectStore(store);
Items.forEach(item => {
req = tx.add(item);
});
return this.result(req);
}
get(store, key) {
let req = this.db.transaction([store], 'readonly')
.objectStore(store).get(key);
return this.result(req);
}
cursor(store) {
let req = this.db.transaction(store).objectStore(store)
.openCursor();
return this.result(req);
}
delete(store, key) {
let req = this.db.transaction([store], 'readwrite')
.objectStore(store).delete(key);
return this.result(req);
}
}
Usage
const employeeData = [
{ id: "00-01", name: "gopal", age: 35, email: "gopal#tutorialspoint.com" },
{ id: "00-02", name: "prasad", age: 32, email: "prasad#tutorialspoint.com" }
];
const idb = new IDB('mydb', 1);
idb.open((db) => {
if (!db.objectStoreNames.contains('user')) {
db.createObjectStore('user', {keyPath: 'id'});
}
});
idb.add('user', employeeData).then(() => alert('Items added')).catch(() => alert('failed'));
But I would prefer the usage with the async/await code
await idb.add('..', ..) // blah blah

cannot write to a characteristic WebBLE

I have this index.html file that talks to Raspberry pi 3 running a bleno app over BLE.
<!-- <!DOCTYPE html> -->
<html>
<head>
<meta charset="utf-8">
<title>bluetooth</title>
<script type="text/javascript">
var serv;
var readVal="";
function onButtonClick() {
console.log('clciked');
let filters = [];
var options1 = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0
};
let options = {};
var tem = '00010000-89BD-43C8-9231-40F6E305F96D'.toLowerCase();
filters.push({services: [tem]});
options.acceptAllDevices = false;
options.filters = filters;
console.log('Requesting Bluetooth Device...');
console.log('with ' + JSON.stringify(options));
var listn;
if(navigator.bluetooth){
document.getElementById('result').innerHTML = "Bluetooth Supported";
}
else{
document.getElementById('result').innerHTML = "Bluetooth not Supported";
}
function success(pos) {
var crd = pos.coords;
console.log(crd);
}
function error(err) {
console.warn(`ERROR(${err.code}): ${err.message}`);
}
console.log(navigator);
navigator.geolocation.getCurrentPosition(success, error, options1);
// navigator.
let decoder = new TextDecoder('utf-8');
navigator.bluetooth.requestDevice(options)
.then(device => {
console.log('> Name: ' + device.name);
console.log('> Id: ' + device.id);
console.log('> Connected: ' + device.gatt.connected);
return device.gatt.connect();
})
.then(server => {
return server.getPrimaryService(tem);
})
.then(service => {
serv = service;
console.log(service);
return service.getCharacteristic('00010010-89bd-43c8-9231-40f6e305f96d');
})
.then(characteristic => {
// console.log(characteristic);
return characteristic.readValue();
})
.then(value => {
let decoder = new TextDecoder('utf-8');
var str = decoder.decode(value);
readVal = str;
console.log(value);
console.log(value.toString());
console.log(str);
})
.catch(error => {
console.log('Argh! ' + error);
});
}
function onSend() {
serv.getCharacteristics().then(characteristics =>{
// console.log(characteristics);
var charact;
for(var i = 0; i < characteristics.length; i++){
var ob = characteristics[i];
if(ob['properties']['write'] === true){
charact = ob;
}
}
console.log(charact);
var Encoder = new TextEncoder("utf-8");
console.log(readVal);
var b = Encoder.encode(readVal);
console.log(b);
charact.writeValue(b);
})
.then(_ => {
console.log('wrote data');
})
.catch(err => {
console.log(err);
});
}
</script>
</head>
<body>
<button id = "b1" onclick="onButtonClick();">Click</button>
<h1 id = 'result'></h1>
<div id = 'networks'></div>
<button id="send" onclick="onSend();">Send Back</button>
</body>
</html>
I can read the characteristics from the ble peripheral, but I get a DOMException GATToperation failed due to reasons unknown at index.html line 0.
My bleno app on the Pi, app.js
var bleno = require('bleno');
var fs = require('fs');
var scannedNetworks = [];
const WIFI_SERVICE_UUID = "00010000-89BD-43C8-9231-40F6E305F96D";
const ARGUMENT_1_UUID = "00010001-89BD-43C8-9231-40F6E305F96D";
const RESULT_UUID = "00010010-89BD-43C8-9231-40F6E305F96D";
class ArgumentCharacteristic extends bleno.Characteristic {
constructor(uuid, name) {
super({
uuid: uuid,
properties: ["write"],
value: null,
descriptors: [
new bleno.Descriptor({
uuid: "2901",
value: name
})
]
});
this.argument = 0;
this.name = name;
}
onWriteRequest(data, offset, withoutResponse, callback) {
try {
if(data.length != 1) {
callback(this.RESULT_INVALID_ATTRIBUTE_LENGTH);
return;
}
this.argument = data.readUInt8();
let decoder = new TextDecoder('utf-8');
var str = decoder.decode(value);
console.log(`Argument ${this.name} is now ${this.argument}`);
console.log(str);
callback(this.RESULT_SUCCESS);
} catch (err) {
console.error(err);
callback(this.RESULT_UNLIKELY_ERROR);
}
}
}
class ResultCharacteristic extends bleno.Characteristic {
constructor() {
super({
uuid: RESULT_UUID,
properties: ["read"],
value: null,
descriptors: [
new bleno.Descriptor({
uuid: "2901",
value: "Calculation result"
})
]
});
//this.calcResultFunc = calcResultFunc;
}
onReadRequest(offset, callback) {
try {
fs.readFile('./weights.txt', (err,dat)=>{
if(!err){
var result = dat.toString();
console.log(`Returning result: ${result}`);
let data = new Buffer(result);
//data.writeUInt8(result, 0);
console.log(data);
callback(this.RESULT_SUCCESS, data);
}
});
} catch (err) {
console.error(err);
callback(this.RESULT_UNLIKELY_ERROR);
}
}
}
console.log("Starting bleno...");
bleno.on("stateChange", state => {
if (state === "poweredOn") {
bleno.startAdvertising("Visualizer thresholds", [WIFI_SERVICE_UUID], err => {
if (err) console.log(err);
});
} else {
console.log("Stopping...");
bleno.stopAdvertising();
}
});
bleno.on("advertisingStart", err => {
console.log("Configuring services...");
if(err) {
console.error(err);
return;
}
let argument1 = new ArgumentCharacteristic(ARGUMENT_1_UUID, "Argument 1");
let result = new ResultCharacteristic();
let calculator = new bleno.PrimaryService({
uuid: WIFI_SERVICE_UUID,
characteristics: [
result,
argument1
]
});
bleno.setServices([calculator], err => {
if(err)
console.log(err);
else
console.log("Services configured");
});
});
// some diagnostics
bleno.on("stateChange", state => console.log(`Bleno: Adapter changed state to ${state}`));
bleno.on("advertisingStart", err => console.log("Bleno: advertisingStart"));
bleno.on("advertisingStartError", err => console.log("Bleno: advertisingStartError"));
bleno.on("advertisingStop", err => console.log("Bleno: advertisingStop"));
bleno.on("servicesSet", err => console.log("Bleno: servicesSet"));
bleno.on("servicesSetError", err => console.log("Bleno: servicesSetError"));
bleno.on("accept", clientAddress => console.log(`Bleno: accept ${clientAddress}`));
bleno.on("disconnect", clientAddress => console.log(`Bleno: disconnect ${clientAddress}`));
Can you guys help me where I am going wrong?
Thanks

Categories

Resources