Creating a ticket generating app to parse to a JSON - javascript

I need help from some of you experienced folks. I am attempting to generate tickets that hold metadata in JSON format. I am a fairly new developer. My idea in this is to take a user and have them create an event with x amount of tickets. The user or our company will then enter the standard input info (venue name, artist name, select seat numbers, sections etc). I want to be able to generate thousands of tickets, each with the correct info that reflects the venue. In general how should I go about this?
Below is me messing around with ways to do this, but I don't have a lot of experience as you can see. I was able to get the tickets to put in String info, but not have seat numbers iterate and increase etc.
import { watchFile, writeFile } from "fs";
import fs from "fs";
class BlockPass_`enter code here`PermanentData {
constructor(venue_Name, artist_Name, genre) {
this.venue_Name = venue_Name;
this.artist_Name = artist_Name;
this.genre = genre;
}
}
let ticket_Omega = new BlockPass_PermanentData(
"Catalyst",
"As I Lay Dying",
"Post-Hardcore Metal"
);
const maxTickets = 10;
function makeTickets(maxTickets) {
const tickets = {};
for (let i = 0; i < maxTickets; i++) {
tickets[i] = ticket_Omega;
}
return tickets;
}
let tickets_Generated = makeTickets(maxTickets);
const ticket_MetaData = JSON.stringify(tickets_Generated);
console.log(ticket_MetaData);
writeFile("JSON/tickets_Omega.JSON", ticket_MetaData, function (err) {
if (err) throw err;
console.log("Omega Tickets generated. Begin Modifications.");
});

The main issue with your code is that you are setting all your tickets to the same object (ticket_Omega). You probably want to generate a new object for every ticket.
I would do something like this instead:
class Event {
constructor(venue_Name, artist_Name, genre) {
this.venue_Name = venue_Name;
this.artist_Name = artist_Name;
this.genre = genre;
}
makeTickets(maxTickets) {
const tickets = {};
for (let i = 0; i < maxTickets; i++) {
tickets[i] = {
seatNumber: i,
sold: false,
venue_Name: this.venue_Name,
artist_Name: this.artist_Name,
genre: this.genre,
};
}
return tickets;
}
}
const some_event = new Event("Catalyst", "As I Lay Dying", "Post-Hardcore Metal");
let tickets = some_event.makeTickets(10);
console.log(tickets);

Related

How to retrieve SmartContract details in react

I'm working on a blockchain project and currently facing the interaction between front-end (react) and smartcontract. I need to retrieve my places that have been pushed on the blockchain to show them on the website:
The smart contract piece that I'm interested interacting to atm:
contract Prenotation {
struct Place{
string name;
string description;
bool isActive; //tells if the place is active
uint256 price; //price per day in wei
address owner; //owner of the place
//keeps score if the place is booked on a particular day
//example: isBooked[4] will denote that the place has been booked on th 3th of Jan
//example 2: isBooked[31] -> the place is booked for the 1th of Feb
bool[] isBooked;
}
//Sequential unique placeId for every new Place
uint256 public placeId;
mapping(uint256 => Place) public places;
...
That's how I tried to retrieve those Places (inside PrenotationContext.jsx):
const getEthereumContract = () => {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const prenotationContract = new ethers.Contract(contractAddress, contractABI, signer);
return prenotationContract;
}
export const PrenotationProvider = ({children}) => {
...
const [places, setPlaces] = useState([]);
...
const fetchAllPlaces = async () => {
try {
if(!ethereum) return alert("Please install MetaMask");
const prenotationContract = getEthereumContract();
const placeId = await prenotationContract.methods.placeId().call()
console.log(placeId)
//return object containing places object
const places = [];
for (var i = 0; i < placeId; i++) {
const place = await prenotationContract.methods.places(i).call();
places.push({
id: i,
name: place.name,
description: place.description,
price: parseInt(place.price._hex) / (10 ** 18)
})
}
setPlaces(places)
} catch (error) {
console.log(error);
throw new Error("No ethereum object");
}
}
I fall into the catch with this error:
TypeError: Cannot read properties of undefined (reading 'placeId')
at fetchAllPlaces (PrenotationContext.jsx:55:57)
at checkIfWalletConnected (PrenotationContext.jsx:82:31)
I tried to verify if I correctly retrieve the contract and logging it on console after calling getEthereumContract I can successfully see it.
Contract inside the web console
In the checkIfWalletConnected I simply call the fetchAllPlaces method.
It's my first project working with solidity, react and all this so I really don't know how to solve it.
In your current for implementation, if extracting fails in the middle of the operation, you are not going to get all places, you will get some of them. Instead
let places
try{
// check if placeId is a string or number. I think Should be string
const placeId = await prenotationContract.methods.placeId().call()
places = await Promise.all(
// since your for loop is till placeId
Array(parseInt(placeId))
.fill()
.map((element, index) => {
// since places is public, solidity assgins a getter automatically
return prenotationContract.methods.places(index).call();
})
);
} catch (e) {
console.log("error in extracting places", e);
}

bsmultiselect: how to get list or array of items picked by the user?

I stumbled upon the bsmultiselect library for a project. The interface looks good but seems like the documentation needs some more work, hence i cannot figure out how to return the list of items selected by the user. I'd appreciate it if someone could give me a hint at least.
here's my code for now:
const instSel = document.getElementById('instrument-select');
let x = new xhr();
x.get("GET", "instruments.json", (rsp) => {
instr = JSON.parse(rsp)
for (i in instr) {
let optGr = document.createElement("optgroup");
optGr.setAttribute("label", instr[i]["name"]);
for (x in instr[i]["instruments"]) {
let opt = document.createElement("option");
opt.setAttribute('value', instr[i]["instruments"][x]);
opt.setAttribute('class', 'dropdown-item');
opt.textContent = instr[i]["instruments"][x];
optGr.appendChild(opt);
}
instSel.appendChild(optGr);
console.log(optGr);
}
bs = dashboardcode.BsMultiSelect("#instrument-select");
console.log(bs);
});
document.body.addEventListener('dblclick', () => {
console.log(bs.getPicks()); // this returns the html only
});
Thanks in advance for any help!
Update
Managed to collect the data by using the e.target event.
instSel.onchange = (e) => {
// loop through all the items
for (let i = 0; i < e.target.length; i++;) {
if (e.target[i].selected) { // if the item is selected
console.log(e.target[i].textContent)
}
}
}

Code not reading the info from the json file

So I'm trying to set up a command to view the amount of candy you have using the info stored in the json file. It doesn't seem to be reading the information correctly.
Here is the command file
const fs = require('fs');
const candyAmount = JSON.parse(fs.readFileSync('./candyheld.json', {encoding:'utf8'}));
const { prefix } = require('../../config.json');
module.exports = {
name: 'candy',
description: 'Displays the amount of candy the user has.',
execute (message, args) {
if (!candyAmount[message.author.id]) return message.channel.send(`You haven\'t started the event yet! Type ${prefix}trickortreat to start!`);
const { candyStored } = candyAmount[message.author.id].candyStored;
message.channel.send(`You have ${candyStored} pieces of candy!`);
},
};
and here is what the json file looks like when it has the info
{"ID":{"candyStored":5}}
I have removed the actual ID number and replaced it with just the word just for this moment. The actual number is in the code.
trickortreat command file
const fs = require('fs');
const candyAmount = JSON.parse(fs.readFileSync('./candyheld.json', {encoding:'utf8'}));
module.exports = {
name: 'trickortreat',
description: 'Special Halloween command',
execute(message, args) {
if (!candyAmount[message.author.id]) {
candyAmount[message.author.id] = {
candyStored: 5
}
fs.writeFile('./candyheld.json', JSON.stringify(candyAmount), err => {
if (err) console.error(err);
});
return message.channel.send('For starting the event, you have been given 5 pieces of candy!');
}
// Stores a random number of candy from 1-3
let candy = Math.floor(Math.random() * 3 + 1);
// Sets the possible messages to be received
let trickortreatmessage = [
'The scarecrow standing behind you jumps out at you and makes you drop all your candy!',
`${message.guild.members.cache.random()} was nice enough to give you Candy! You got ${candy} pieces of candy!`,
`Oh no you asked ${message.guild.members.cache.random()} for Candy and they decided to egg you instead!`
]
// Store one of the random messages
const trickortreat = trickortreatmessage[Math.floor(Math.random() * trickortreatmessage.length)];
if (trickortreat == trickortreatmessage[0]) {
candyAmount[message.author.id].candyStored = 0;
} else if (trickortreat == trickortreatmessage[1]) {
candyAmount[message.author.id].candyStored = candyAmount[message.author.id].candyStored + candy;
}
fs.writeFile('./candyheld.json', JSON.stringify(candyAmount), err => {
if (err) console.error(err);
});
message.channel.send(trickortreat);
},
};
I've been adding some new things and trying to fix this issue and I got an update that will hopefully help figure this out. I made an "addcandy" command to add candy to specific users mentioned. When I use the command, and then use /candy, it reads it perfectly.
So I'm thinking #ericgio was right in that it has something to do with the "trickortreat" command. It adds the number fine but for some reason "candy" isn't reading that change. But it reads the change when I use "addcandy"
So I managed to figure out for anyone else having the same issue. I changed the "const candyAmount" to just be "require('../../candyheld.json') and did the same for my other files and it seems to read correctly now
old code line
const candyAmount = JSON.parse(fs.readFileSync('./candyheld.json', {encoding:'utf8'}));
new code line
const candyAmount = require('../../candyheld.json');

Preventing duplicate value in local storage

I'm creating a library archive site containing a collection of my favorite reads. I have a click event listener on the books, adding them to my local storage key 'books' when doing so. I want it so that, if I click on the same book twice, it won't be added as a duplicate value in my ls. I've tried things I've found on here like an "if" statement checking the index of the new 'book' and comparing it to others, as well as filtering, but to no avail.
document.querySelectorAll('.card').forEach(function(uibook){
let arr = []
for(i=0;i < uibook.length; i++){
arr.push(uibook[i])
console.log(arr)
return arr
}
uibook.addEventListener('click',function(){
window.document.location = './details.html'
const title = uibook.innerText
const summary = uibook.querySelector('.card-summary').innerText
const genre = uibook.querySelector('.card-genre').innerText
const author = uibook.querySelector('.card-author').innerText
const page = uibook.querySelector('.card-page').innerText
const img = uibook.querySelector('img.card-img-top').getAttribute('src');
// Instantiate book
const Nbook = new book(title,genre,author,page,summary,img);
console.log(Nbook)
if (localStorage.getItem('books') === null){
books = [];
}
else{
books = JSON.parse(localStorage.getItem('books'));
}
books.push(Nbook)
localStorage.setItem('books', JSON.stringify(books));
// localStorage.clear();
add('lastKey',Nbook)
})
})
var lastKey;
function add(key,value) {
lastKey = key;
console.log(value)
localStorage.setItem(lastKey, JSON.stringify(value));
}
////////////////DETAILS PAGE/////////////////////////
function getBooks(){
// let lastKey;
if(localStorage.getItem('lastKey') === null){
lastKey = [];
} else {
lastKey = JSON.parse(localStorage.getItem('lastKey'));
}
console.log(lastKey)
//details info UI
document.querySelector('.details-title').innerText = `${lastKey.title}`
var imgTest = document.querySelector('.details-img').src = `${lastKey.img}`
console.log(imgTest)
document.querySelector('.summary-text').innerText = `${lastKey.summary}`
document.querySelector('.genre-text').innerText = `${lastKey.genre}`
console.log(document.querySelector('.author-text').innerText = `${lastKey.author}`)
document.querySelector('.pageNum-text').innerText = `${lastKey.page}`
}
getBooks()
Edit: updated the code I should also add that I have 2 keys in my ls. One is the 'lastkey', which as you may have guessed just has the value of the last book that was clicked on. This is to output the details of the book on the following page. The 'book' key is to have all of the books that I click on w/o duplicates. The purpose is b/c I have a carousel at the bottom of the page where I want to output suggested books by their genre, and I don't want to have duplicates of the same books. knowwhatimean?
To make comparison easy, you could have the books array be an array of JSON strings that you can compare with === or .includes:
if (localStorage.getItem('books') === null) {
books = [];
} else {
books = JSON.parse(localStorage.getItem('books'));
}
const stringified = JSON.stringify(Nbook);
if (!books.includes(stringified)) {
books.push(stringified);
}
localStorage.setItem('books', JSON.stringify(books));
Then, when parsing books elsewhere, call JSON.parse on array items to get to the underlying object, eg
const books = JSON.parse(localStorage.getItem('books')).map(JSON.parse);
// console.log(book[0].title)
Search your books array for another book with the same title.
uibook.addEventListener('click', function() {
window.document.location = './details.html'
const title = uibook.innerText
if (localStorage.getItem('books') === null) {
books = [];
} else {
books = JSON.parse(localStorage.getItem('books'));
}
const foundBook = books.find(book => book.title == title);
if (!foundBook) {
// Instantiate book
const summary = uibook.querySelector('.card-summary').innerText
const genre = uibook.querySelector('.card-genre').innerText
const author = uibook.querySelector('.card-author').innerText
const page = uibook.querySelector('.card-page').innerText
const img = uibook.querySelector('img.card-img-top').getAttribute('src');
const Nbook = new book(title, genre, author, page, summary, img);
books.push(Nbook);
console.log(Nbook)
localStorage.setItem('books', JSON.stringify(books));
add('lastKey', Nbook)
} else {
add('lastKey', foundBook);
}
})

How do I wait until entire array is pushed to execute a function?

I am creating a payout API for my site, this one is set up around Monero and I am fetching the values needed to make payments and where to send them from my MongoDB database. I am using Mongoose to do this
I have everything mapped out, it grabs from an array the total net value for that day that needs to be paid out and it grabs from another array the latest wallet entry so it knows where to send the amount to.
The problem arises when I'm trying to structure a new array with this data, pushing this data into it.
Monero intrinsically only allows one transaction to be sent out at a time, locking your leftover balance and the amount sent out until that one transaction has been fully confirmed. The one transaction can be split into multiple transactions but it all has to be sent as "one" big chunk.
So when I send the request to Monero it has to include an array of every wallet and what amount each wallet is receiving.
When I'm pushing to the array I noticed it executes the Transfer Monero function for every time it pushes to the array. How do I make it so the array is pushed completely first with every possible value that meets my if statement (Date is today, paymentStatus is set to false, the amount due is not equal or below 0) before sending that variable over for the Transfer Monero function to use?
I've already tried using return functions, etc. Not sure how to implement async/await or Promises
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var moment = require('moment');
var User = require('../models/user');
var moneroWallet = require('monero-nodejs');
var Wallet = new moneroWallet('127.0.0.1', 18083);
var destinations = []
var xmrnet = []
// connect to MongoDB
mongoose.connect('mongodb://)
// Fetch IDs
function getID(){
var cursor = User.find({}, function (err, users) {
}).cursor();
return cursor;
}
var cursor = getID();
cursor.on('data', function(name){
var id = name.id
// Map all users using IDs
function getUsers(){
var cursor = User.findById(id, function (err, users) {
}).cursor();
return cursor;
}
var cursor = getUsers();
cursor.on('data', function(user){
net = user.netHistory.map(element => element)
order = user.orderHistory.map(element => element)
userWallets = user.userWallets.map(element => element)
var today = moment();
// date is today? validation
for (var i = 0; i < net.length; i++){
netDate = net[i].net_date_time
netStatus = net[i].paymentStatus
netUSD = net[i].current_usd_net
xmrnet = net[i].xmr_net
for (var j = 0; j < userWallets.length; j++){
xmrwalletsU = userWallets[j].xmr_wallet
if(xmrwalletsU !== ''){
xmrwallet = xmrwalletsU
}
}
var Dateistoday = moment(netDate).isSame(today, 'day');;
if (Dateistoday === true && xmrnet !== 0 && netStatus === false){
console.log('its true')
netid = net[i].id
var destinationsU = [{amount: xmrnet, address: xmrwallet}]
destinations.push(destinationsU)
console.log(destinations)
// problem is right here with destinations^ it pushes one by one
// problem over here as well as wallet.transfer executes one by one by the time it gets to the second, the balance is already locked, unable to send
Wallet.transfer(destinations).then(function(transfer) {
console.log(transfer);
var payouts = {
payout_date_time: Date(),
payout_usd_amount: netUSD,
xmr_wallet: xmrwallet,
xmr_txid: transfer.tx_hash,
}
// add payout to payoutHistory array
User.findByIdAndUpdate(id, {"$addToSet": { 'payoutHistory': [payouts]}},
function(err, user) {
if(err) { console.log(err) }
else {
console.log()
};
})
// update paymentStatus of specific net entry to true
User.updateMany({
"_id": id,
"netHistory._id": netid
}, {
"$set": {
"netHistory.$.paymentStatus": true
}
}, function(error, success) {
})
})
}
}
})
})

Categories