I'm new to machine learning and i used an mnist demo model to train a cat and dog classifier.But it doesn't seem to work very well.Here are some diagrams of the model:
It seems that this model always predicts any input as a cat.
This is my code. Please help me.
index.js:
import {IMAGE_H, IMAGE_W, MnistData} from './data.js';
import * as ui from './ui.js';
let classNum = 0;
function createConvModel() {
const model = tf.sequential();
model.add(tf.layers.conv2d({
inputShape: [IMAGE_H, IMAGE_W, 3],
kernelSize: 5,
filters: 32,
activation: 'relu'
}));
model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2}));
model.add(tf.layers.conv2d({kernelSize: 5, filters: 32, activation: 'relu'}));
model.add(tf.layers.maxPooling2d({poolSize: 2, strides: 2}));
model.add(tf.layers.conv2d({kernelSize: 5, filters: 64, activation: 'relu'}));
model.add(tf.layers.flatten({}));
model.add(tf.layers.dense({units: 64, activation: 'relu'}));
model.add(tf.layers.dense({units: classNum, activation: 'softmax'}));
return model;
}
function createDenseModel() {
const model = tf.sequential();
model.add(tf.layers.flatten({inputShape: [IMAGE_H, IMAGE_W, 3]}));
model.add(tf.layers.dense({units: 42, activation: 'relu'}));
model.add(tf.layers.dense({units: classNum, activation: 'softmax'}));
return model;
}
async function train(model, fitCallbacks) {
ui.logStatus('Training model...');
const optimizer = 'rmsprop';
model.compile({
optimizer,
loss: 'categoricalCrossentropy',
metrics: ['accuracy'],
});
const batchSize = 64;
const trainEpochs = ui.getTrainEpochs();
let trainBatchCount = 0;
const trainData = data.getTrainData();
const valData = data.getValData();
const testData = data.getTestData();
await model.fit(trainData.xs, trainData.labels, {
batchSize:batchSize,
validationData:[valData.xs,valData.labels],
shuffle:true,
epochs: trainEpochs,
callbacks: fitCallbacks
});
console.log("complete");
const classNames = ['cat','dog'];
const [preds, labels] = doPrediction(model,testData);
const classAccuracy = await tfvis.metrics.perClassAccuracy(labels, preds);
const container = { name: 'Accuracy', tab: 'Evaluation' };
tfvis.show.perClassAccuracy(container, classAccuracy, classNames);
}
function doPrediction(model,testData) {
const testxs = testData.xs;
const labels = testData.labels.argMax([-1]);
const preds = model.predict(testxs).argMax([-1]);
testxs.dispose();
return [preds, labels];
}
function createModel() {
let model;
const modelType = ui.getModelTypeId();
if (modelType === 'ConvNet') {
model = createConvModel();
} else if (modelType === 'DenseNet') {
model = createDenseModel();
} else {
throw new Error(`Invalid model type: ${modelType}`);
}
return model;
}
async function watchTraining(model) {
const metrics = ['loss', 'val_loss', 'acc', 'val_acc'];
const container = {
name: 'charts', tab: 'Training', styles: { height: '1000px' }
};
const callbacks = tfvis.show.fitCallbacks(container, metrics);
return train(model, callbacks);
}
let data;
async function load() {
tf.disableDeprecationWarnings();
classNum = await localforage.getItem('classNum');
tfvis.visor();
data = new MnistData();
await data.load();
}
ui.setTrainButtonCallback(async () => {
ui.logStatus('Loading data...');
await load();
ui.logStatus('Creating model...');
const model = createModel();
model.summary();
ui.logStatus('Starting model training...');
await watchTraining(model);
});
data.js:
export const IMAGE_H = 64;
export const IMAGE_W = 64;
const IMAGE_SIZE = IMAGE_H * IMAGE_W;
let NUM_CLASSES = 0;
let trainImagesLabels;
let testLabels;
let trainImages ;
let testImages ;
let validateImages;
let validateLabels;
let validateSplit = 0.2;
let modelId;
let classNum;
/**
* A class that fetches the sprited MNIST dataset and provide data as
* tf.Tensors.
*/
export class MnistData {
constructor() {}
//shuffle
static shuffleSwap(arr1,arr2) {
if(arr1.length == 1) return {arr1,arr2};
let i = arr1.length;
while(--i > 1) {
let j = Math.floor(Math.random() * (i+1));
[arr1[i], arr1[j]] = [arr1[j], arr1[i]];
[arr2[i], arr2[j]] = [arr2[j], arr2[i]];
}
return {arr1,arr2};
}
async load() {
//get data from localforage
this.trainImages = await localforage.getItem('dataset');
this.trainImagesLabels = await localforage.getItem('datasetLabel');
this.modelId = await localforage.getItem('modelId');
this.classNum = await localforage.getItem('classNum');
this.trainImages.shift();
this.trainImagesLabels.shift();
//construct the validateData
let status = false;
let maxVal = Math.floor(this.trainImages.length * 0.2);
this.validateImages = new Array();
this.validateLabels = new Array();
for(let i=0;i<maxVal;i++){
if(status){
this.validateImages.push(this.trainImages.pop());
this.validateLabels.push(this.trainImagesLabels.pop());
status = false;
}else{
this.validateImages.push(this.trainImages.shift());
this.validateLabels.push(this.trainImagesLabels.shift());
status = true;
}
}
//construct the testData
this.testImages = new Array();
this.testLabels = new Array();
for(let i=0;i<maxVal;i++){
if(status){
this.testImages.push(this.trainImages.pop());
this.testLabels.push(this.trainImagesLabels.pop());
status = false;
}else{
this.testImages.push(this.trainImages.shift());
this.testLabels.push(this.trainImagesLabels.shift());
status = true;
}
}
//shuffle
let val = MnistData.shuffleSwap(this.validateImages,this.validateLabels);
this.validateImages = val.arr1;
this.validateLabels = val.arr2;
let train = MnistData.shuffleSwap(this.trainImages,this.trainImagesLabels);
this.trainImages = train.arr1;
this.trainImagesLabels = train.arr2;
}
getTrainData() {
const xs = tf.tensor4d(this.trainImages);
const labels = tf.oneHot(tf.tensor1d(this.trainImagesLabels,'int32'),this.classNum);
return {xs, labels};
}
getValData() {
const xs = tf.tensor4d(this.validateImages);
const labels = tf.oneHot(tf.tensor1d(this.validateLabels,'int32'),this.classNum);
return {xs, labels};
}
getTestData() {
const xs = tf.tensor4d(this.testImages);
const labels = tf.oneHot(tf.tensor1d(this.testLabels,'int32'),this.classNum);
return {xs, labels};
}
}
I added some pictures at the beginning.
//getclassNum
function getClassNum(files) {
let classArr = new Array();
let dirArr = new Array();
let imageNum = 0;
for (let i = 0; i < files.length; i++) {
if (files[i].type.split('/')[0] == 'image' && files[i].type.split('/')[1] == 'jpeg') {
dirArr = files[i].webkitRelativePath.split('/');
let currentClassIndex = dirArr.length - 2;
let isExist = false;
if (currentClassIndex <= 0)
isExist = true;
else {
imageNum++;
}
if (classArr == null) {
classArr.push(dirArr[currentClassIndex]);
}
for (let j = 0; j < classArr.length; j++) {
if (classArr[j] == dirArr[currentClassIndex]) {
isExist = true;
}
}
if (!isExist) {
classArr.push(dirArr[currentClassIndex]);
}
}
}
let classNum = classArr.length;
return {classNum, imageNum, classArr};
}
//get nested array
function getDataset(files, classArr,imgNum) {
let trainLabelArr = new Array();
let trainDataArr = new Array();
for (let i = 0; i < files.length; i++) {
if (files[i].type.split('/')[0] == 'image'&& files[i].type.split('/')[1] == 'jpeg') {
let dirArr = files[i].webkitRelativePath.split('/');
let currentClassIndex = dirArr.length - 2;
if (currentClassIndex >= 0) {
for(let j=0;j<classArr.length;j++){
if(dirArr[currentClassIndex]==classArr[j]){
let reader = new FileReader();
reader.readAsDataURL(files[i]);
reader.onload = function () {
document.getElementById('image').setAttribute( 'src', reader.result);
let tensor= tf.browser.fromPixels(document.getElementById('image'));
let nest = tensor.arraySync();
trainDataArr.push(nest);
trainLabelArr.push(j);
}
}
}
}
}
}
return{trainDataArr,trainLabelArr,trainDataLength}
}
//getfiles
async function fileChange(that) {
let files = that.files;
let container = getClassNum(files);
let data = getDataset(files, container.classArr,container.imageNum);
let trainDataArr = data.trainDataArr;
let trainLabelArr = data.trainLabelArr;
setTimeout(function () {
localforage.setItem('dataset',trainDataArr,function (err,result) {
});
localforage.setItem('datasetLabel',trainLabelArr,function (err,result) {
});
localforage.setItem('modelId',modelId,function (err,result) {
});
localforage.setItem('classNum',container.classNum,function (err,result) {
});
},container.imageNum * 10);
}
}
Let me answer my question. After a day of testing, I found that this model needs a lot of data. Each category requires at least 1,000 images. If there is not enough training data, the model can only output one result. Moreover, this model performs very well in recognizing objects with fewer characters such as letters and signs, and not very well in recognizing animals or natural environments.
Related
We needed to create a Live Monitor sort of screen that gets the feed through a WebSocket. Angular 11 is used for the UI part. When the page is left on Chrome for a few minutes, the memory heap starts increasing and gradually it increases to a greater extent. After some time, the application will hang and we can't go to another page of the application.
I'm unable to understand the cause of the memory leak, if any.
HTML Code:
<ag-grid-angular #LiveHedgeGrid class="ag-theme-balham" [rowData]="hedgeRowData" [columnDefs]="hedgeColumn" (gridReady)="onLiveHedgeReady($event)" (columnRowGroupChanged)="oncolumnRowGroupChanged($event)" (gridSizeChanged)="onGridSizeChanged($event)"
[enableCellChangeFlash]="true" [rowBuffer]="10" [debounceVerticalScrollbar]="true" [suppressColumnVirtualisation]="true" [groupIncludeTotalFooter]="true" [gridOptions]="gridOptions" [suppressAggFuncInHeader]="true" [groupDefaultExpanded]="groupDefaultExpanded"
[domLayout]="domLayout">
</ag-grid-angular>
TypeScript Code:
websocketCall() {
let socket = new WebSocket(ApiService.webSocketUrl);
socket.onopen = e => {
};
socket.onmessage = e => {
let server_message;
try {
server_message = JSON.parse(e.data);
server_message = JSON.parse(server_message);
if (server_message instanceof Array) {
this.bindTableValues(server_message);
} else {
this.bindTableValues([server_message]);
}
} catch (e) {
this.bindTableValues(server_message);
}
// console.log('socket open');
};
socket.onclose = () => {
//console.log('Web Socket Connection Closed');
};}
async bindTableValues(server_message) {
await server_message.forEach(element => {
this.ricData = {};
let ricPeriod = '';
let itemsToUpdate = [];
let data = {};
let value = 0;
let ricData = this.ricList[element['RIC']];
if (ricData) {
if (ricData['type'] == 'swap') {
value = element['Fields']['NETCHNG_1'];
ricPeriod = ricData['disp_name'];
ricPeriod = ricPeriod.toString().trim().substring(0, ricPeriod.length - 1).toLowerCase();
if (value) {
//const itemsToUpdate: any[] = [];
this.gridApi.forEachNodeAfterFilterAndSort((rowNode) => {
if(!rowNode.group) {
data = rowNode.data;
if(data['Tenor'] == ricPeriod) {
data['LivePnL'] = parseFloat(data['DV01']) * value * 100;
itemsToUpdate.push(data);
}
}
});
// this.gridApi.applyTransaction({ update: itemsToUpdate })!;
// this.gridApi.applyTransactionAsync({ update: itemsToUpdate })!;
this.gridApi.batchUpdateRowData({ update: itemsToUpdate })!;
};
}
};
});}
ngOnDestroy(): void {
try {
//console.log('Destroy ' + this.socket.readyState);
// if (this.socket.readyState === WebSocket.OPEN) {
if (this.socket.readyState === 1) {
this.socket.close();
}
this.getRic.unsubscribe();
this.getTable.unsubscribe();
}
catch (e) {
console.log(e);
}}
HERE IS MY CODE,
let subjects: string[] = ['Mathemetics-70', 'Science-67', 'English-88', 'Geography-62', 'ComputerSc-55'];
function uppercase(subject: string) {
return subject.toUpperCase();
}
let subjects_upppercase = subjects
.map(uppercase)
.toString()
.match(/\d+/g)
.map(function (numbers) {
return parseInt(numbers);
})
.filter(function (number) {
if (number > 65) {
return true;
}
})
.map(function (newarray) {
return newarray;
});
console.log(subjects_upppercase);
I have an array of numbers [70,67,88]
now I want to print names of subjects corresponding to the numbers inside an array.
can someone help with this, please?
here is a solution (I didnt quite get what your requirements where but here you go)
const subjects: string[] = ["Mathemetics-70","Science-67","English-88","Geography-62","ComputerSc-55"];
const pairs = subjects.map(subject => {
const subjectNumber = subject.match( /\d+/);
if (!subjectNumber) return undefined;
return [parseInt(subjectNumber[0]), subject.toUpperCase()]
}).filter(Boolean)
const obj = Object.fromEntries(pairs);
console.log(obj); // this will be { number: subject }
// and if you want to print only your numbers use
const toPrint = [70,67,88];
for (let numberToPrint of toPrint){
console.log(obj[numberToPrint]);
}
It is my solution, the code is:
let subjects: string[] = ['Mathemetics-70', 'Science-67', 'English-88', 'Geography-62', 'ComputerSc-55'];
const str = subjects.join("\n");
const arr = [70, 67, 88].map((num) => {
return str.match(new RegExp("(\\w+\-)" + num))[0];
});
console.log(arr);
// ['Mathemetics-70', 'Science-67', 'English-88']
This question already has an answer here:
Discord.js v12 code breaks when upgrading to v13
(1 answer)
Closed 1 year ago.
So basically I had this blackjack command that worked fine with v12 discord.js but as soon as I updated to discord v13. Bugs starting to appear like:
node:5932) DeprecationWarning: The message event is deprecated. Use messageCreate instead
(Use node --trace-deprecation ... to show where the warning was created)
(Only error showing up)
So I made some research and figured out that what happens to embed, but this command does not content an embed.. I came here to ask help. I would appreciate it :)
Blackjack.js
const { stripIndents } = require('common-tags');
const { shuffle, verify } = require('../../functions');
const db = require('quick.db');
const suits = ['♣', '♥', '♦', '♠'];
const faces = ['Jack', 'Queen', 'King'];
const hitWords = ['hit', 'hit me'];
const standWords = ['stand'];
module.exports = {
config: {
name: 'blackjack',
aliases: ['bj'],
category: 'games',
usage: '[deck] <bet>',
description: 'Play A Game Of Blackjack!',
accessableby: 'everyone'
},
run: async (bot, message, args, ops) => {
if (!args[0]) return message.channel.send('**Please Enter Your Deck Amount!**')
let deckCount = parseInt(args[0])
if (isNaN(args[0])) return message.channel.send('**Please Enter A Number!**')
if (deckCount <= 0 || deckCount >= 9) return message.channel.send("**Please Enter A Number Between 1 - 8!**")
let user = message.author;
let bal = db.fetch(`money_${user.id}`)
if (!bal === null) bal = 0;
if (!args[1]) return message.channel.send("**Please Enter Your Bet!**")
let amount = parseInt(args[1])
if (isNaN(args[1])) return message.channel.send("**Please Enter A Number**")
if (amount > 10000) return message.channel.send("**Cannot Place Bet More Than \`10000\`**")
if (bal < amount) return message.channel.send("**You Are Betting More Than You Have!**")
const current = ops.games.get(message.channel.id);
if (current) return message.channel.send(`**Please Wait Until The Current Game Of \`${current.name}\` Is Finished!**`);
try {
ops.games.set(message.channel.id, { name: 'blackjack', data: generateDeck(deckCount) });
const dealerHand = [];
draw(message.channel, dealerHand);
draw(message.channel, dealerHand);
const playerHand = [];
draw(message.channel, playerHand);
draw(message.channel, playerHand);
const dealerInitialTotal = calculate(dealerHand);
const playerInitialTotal = calculate(playerHand);
if (dealerInitialTotal === 21 && playerInitialTotal === 21) {
ops.games.delete(message.channel.id);
return message.channel.send('**Both Of You Just Hit Blackjack!**');
} else if (dealerInitialTotal === 21) {
ops.games.delete(message.channel.id);
db.subtract(`money_${user.id}`, amount);
return message.channel.send(`**The Dealer Hit Blackjack Right Away!\nNew Balance - **\` ${bal - amount}\``);
} else if (playerInitialTotal === 21) {
ops.games.delete(message.channel.id);
db.add(`money_${user.id}`, amount)
return message.channel.send(`**You Hit Blackjack Right Away!\nNew Balance -**\`${bal + amount}\``);
}
let playerTurn = true;
let win = false;
let reason;
while (!win) {
if (playerTurn) {
await message.channel.send(stripIndents`
**First Dealer Card -** ${dealerHand[0].display}
**You [${calculate(playerHand)}] -**
**${playerHand.map(card => card.display).join('\n')}**
\`[Hit / Stand]\`
`);
const hit = await verify(message.channel, message.author, { extraYes: hitWords, extraNo: standWords });
if (hit) {
const card = draw(message.channel, playerHand);
const total = calculate(playerHand);
if (total > 21) {
reason = `You Drew ${card.display}, Total Of ${total}! Bust`;
break;
} else if (total === 21) {
reason = `You Drew ${card.display} And Hit 21!`;
win = true;
}
} else {
const dealerTotal = calculate(dealerHand);
await message.channel.send(`**Second Dealer Card Is ${dealerHand[1].display}, Total Of ${dealerTotal}!**`);
playerTurn = false;
}
} else {
const inital = calculate(dealerHand);
let card;
if (inital < 17) card = draw(message.channel, dealerHand);
const total = calculate(dealerHand);
if (total > 21) {
reason = `Dealer Drew ${card.display}, Total Of ${total}! Dealer Bust`;
win = true;
} else if (total >= 17) {
const playerTotal = calculate(playerHand);
if (total === playerTotal) {
reason = `${card ? `Dealer Drew ${card.display}, Making It ` : ''}${playerTotal}-${total}`;
break;
} else if (total > playerTotal) {
reason = `${card ? `Dealer Drew ${card.display}, Making It ` : ''}${playerTotal}-\`${total}\``;
break;
} else {
reason = `${card ? `Dealer Drew ${card.display}, Making It ` : ''}\`${playerTotal}\`-${total}`;
win = true;
}
} else {
await message.channel.send(`**Dealer Drew ${card.display}, Total Of ${total}!**`);
}
}
}
db.add(`games_${user.id}`, 1)
ops.games.delete(message.channel.id);
if (win) {
db.add(`money_${user.id}`, amount);
return message.channel.send(`**${reason}, You Won ${amount}!**`);
} else {
db.subtract(`money_${user.id}`, amount);
return message.channel.send(`**${reason}, You Lost ${amount}!**`);
}
} catch (err) {
ops.games.delete(message.channel.id);
throw err;
}
function generateDeck(deckCount) {
const deck = [];
for (let i = 0; i < deckCount; i++) {
for (const suit of suits) {
deck.push({
value: 11,
display: `${suit} Ace!`
});
for (let j = 2; j <= 10; j++) {
deck.push({
value: j,
display: `${suit} ${j}`
});
}
for (const face of faces) {
deck.push({
value: 10,
display: `${suit} ${face}`
});
}
}
}
return shuffle(deck);
}
function draw(channel, hand) {
const deck = ops.games.get(channel.id).data;
const card = deck[0];
deck.shift();
hand.push(card);
return card;
}
function calculate(hand) {
return hand.sort((a, b) => a.value - b.value).reduce((a, b) => {
let { value } = b;
if (value === 11 && a + value > 21) value = 1;
return a + value;
}, 0);
}
}
};
Event Handler:
const { readdirSync } = require("fs")
module.exports = (bot) => {
const load = dirs => {
const events = readdirSync(`./events/${dirs}/`).filter(d => d.endsWith('.js'));
for (let file of events) {
const evt = require(`../events/${dirs}/${file}`);
let eName = file.split('.')[0];
bot.on(eName, evt.bind(null, bot));
};
};
["client", "guild"].forEach(x => load(x));
};
message is an event. you have an event handler, which fires, when a message event is triggered by a user. (they send a message).
What this error is saying is that the message event is deprecated. messageCreate (or messageUpdate) are the new events, and your event handlers need to use that syntax to address the message events (accordingly to creation or update).
I have the following code written and I am not sure why the second level menu items are always the same for each primary level. I know this might be related with scope variables. Can you please suggest an alternative?
``
editor.ui.registry.addMenuButton(insertFields, {
text: My button,
fetch: function (callback) {
var temp = [];
for(var i = 0; i < k.state.ListItems.length; i++)
{
var obj = {};
var fieldItems = k.state.ListItems[i].description;
console.log(fieldItems);
obj["text"] = k.state.ListItems[i].Title;
obj["type"] = "nestedmenuitem";
obj["getSubmenuItems"] = () => {
console.log("fired for submenu");
var getMenuItem = t => {
return {
type: "menuitem",
text: t,
onAction: () => {
editor.insertContent("{{ " + t + "}}");
}
};
};
var nestedItems = [];
for (let k = 0; k < fieldItems.length; k++) {
nestedItems.push(getMenuItem(fieldItems[k].Title ));
}
return nestedItems;
}
temp.push(obj);
console.log(temp);
}
console.log(temp);
var items = temp;
callback(items);
}
});
}
}}
/>
was able to resolve this issue. Not sure if there was a better way.
setup: function (editor) {
for(let i = 0; i < k.state.ListItems.length;i++)
{
// let Fields = k.state.ListItems[i].Fields;
editor.ui.registry.addNestedMenuItem(k.state.ListItems[i].Id, {
text: k.state.ListItems[i].Title,
getSubmenuItems: () => {
var getMenuItem = (t,r) => {
return {
type: "menuitem",
text: t,
onAction: () => {
editor.insertContent("{{" + r +"|" + t + "}}");
}
};
};
var nestedItems = [];
for (let j = 0; j < k.state.ListItems[i].Fields.length; j++) {
// console.log(Fields[j].Title);
nestedItems.push(getMenuItem(k.state.ListItems[i].Fields[j].Title,k.state.ListItems[i].Title));
}
return nestedItems;
}
});
}
}
I have a react app, in which im hiding and showing buttons instead of moving across pages, before I show the next button I want to make sure the function the button was meant to call has completed. Here is what I have so far:
This is the Async function:
async handleTransferFromEthereum(){
parseAddress(this.state.sc)
this.setState(prevState => ({
isEthTransferVisible: !prevState.isEthTransferVisible,
isGoDeployedVisible: !prevState.isGoDeployedVisible
}));
}
and this would be the function im calling:
import ERC20ABI from './blockchain/ERC20ABI.js';
import ethweb3 from './blockchain/ethweb3.js';
import _ from 'lodash';
var addressesValues = [];
var uniqueAddresses = [];
var values = [];
var count = 0;
var map = {};
var address =[];
var amounts=[];
var choppedAdrresses = [];
export function parseAddress(_smartcontract){
console.log("Scanning blockchain")
var contractObj = new ethweb3.eth.Contract(ERC20ABI,_smartcontract);
contractObj.getPastEvents(
'Transfer' || 'allEvents',
{
fromBlock: 0,
toBlock: 'latest'
},
function(err,res){
for(var i =1; i< res.length; i++){
if (uniqueAddresses.includes(res[i].returnValues.from)===false) {
uniqueAddresses[count] = res[i].returnValues.from;
values[count] = parseInt(0);
map[uniqueAddresses[count]] = values[count];
count+=1
}
if (uniqueAddresses.includes(res[i].returnValues.to)===false){
uniqueAddresses[count] = res[i].returnValues.to;
values[count] = parseInt(0);
map[uniqueAddresses[count]] = values[count];
count+=1
}
}
for(var j = 0; j< res.length; j++){
map[res[j].returnValues.from] -= parseInt(res[j].returnValues.value);
map[res[j].returnValues.to] += parseInt(res[j].returnValues.value);
}
for(var x = 0; x < uniqueAddresses.length; x++){
addressesValues.push([uniqueAddresses[x], parseInt(map[res[x].returnValues.to])])
}
for(var y=0; y < addressesValues.length; y++){
address.push(addressesValues[y][0]);
amounts.push(addressesValues[y][1]);
}
var choppedAdrresses=_.chunk(address, 100);
var choppedValue=_.chunk(amounts, 100);
var tokenSum = amounts.reduce((a, b) => a + b, 0);
sessionStorage.setItem("addresses", JSON.stringify(address))
sessionStorage.setItem("tokenSum", JSON.stringify(tokenSum))
sessionStorage.setItem("choppedAdrresses", JSON.stringify(choppedAdrresses))
sessionStorage.setItem("choppedValue", JSON.stringify(choppedValue))
}
);
}
Any pointers would really help.
You need to wait on a promise, but since the getPastEvents function works in a callback pattern, you could create a custom promise and return it from parseAddress method
export function parseAddress(_smartcontract){
console.log("Scanning blockchain")
return new Promise(function(resolve, reject) {
var contractObj = new ethweb3.eth.Contract(ERC20ABI,_smartcontract);
contractObj.getPastEvents(
'Transfer' || 'allEvents',
{
fromBlock: 0,
toBlock: 'latest'
},
function(err,res){
if (err) {
reject(err);
}
for(var i =1; i< res.length; i++){
if (uniqueAddresses.includes(res[i].returnValues.from)===false) {
uniqueAddresses[count] = res[i].returnValues.from;
values[count] = parseInt(0);
map[uniqueAddresses[count]] = values[count];
count+=1
}
if (uniqueAddresses.includes(res[i].returnValues.to)===false){
uniqueAddresses[count] = res[i].returnValues.to;
values[count] = parseInt(0);
map[uniqueAddresses[count]] = values[count];
count+=1
}
}
for(var j = 0; j< res.length; j++){
map[res[j].returnValues.from] -= parseInt(res[j].returnValues.value);
map[res[j].returnValues.to] += parseInt(res[j].returnValues.value);
}
for(var x = 0; x < uniqueAddresses.length; x++){
addressesValues.push([uniqueAddresses[x], parseInt(map[res[x].returnValues.to])])
}
for(var y=0; y < addressesValues.length; y++){
address.push(addressesValues[y][0]);
amounts.push(addressesValues[y][1]);
}
var choppedAdrresses=_.chunk(address, 100);
var choppedValue=_.chunk(amounts, 100);
var tokenSum = amounts.reduce((a, b) => a + b, 0);
sessionStorage.setItem("addresses", JSON.stringify(address))
sessionStorage.setItem("tokenSum", JSON.stringify(tokenSum))
sessionStorage.setItem("choppedAdrresses", JSON.stringify(choppedAdrresses))
sessionStorage.setItem("choppedValue", JSON.stringify(choppedValue))
resolve();
}
);
});
}
After this, you can use await like
async handleTransferFromEthereum(){
await parseAddress(this.state.sc)
this.setState(prevState => ({
isEthTransferVisible: !prevState.isEthTransferVisible,
isGoDeployedVisible: !prevState.isGoDeployedVisible
}));
}
However if its possible try to convert getPastEvents so that it returns a promise instead of using a callback
The promise starts when you create it and await will wait for it to resolve. But the code in the middle of these two statements will run before the promise ends. If you don't need any result of the promise you can put code in that zone to paralelize the execution of it with the promise.
const timeBomb = (resolve, reject) => {
const msleft = Math.random() * 700 + 200;
console.log("Countdown started!");
console.log("Only "+(Math.round(msleft)/1000)+" seconds left!!");
setTimeout(resolve, msleft);
};
waiter = async (p) => {
console.log("I will hurry to do my last wish before dying");
const result = await p;
console.log("It Exploded!");
}
waiter(new Promise(timeBomb));