Cannot read properties of undefined (reading '_hex') Next js buyNft - next.js

so I am building an nft marketplace and everything is good with creating nft .. etc but when attempting to buy an nft I get this error :
ethers.umd.js?e6ac:4395 Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '_hex')
Here is the code snippet:
const buyNft = async (nft) => {
const web3Modal = new Web3Modal();
const connection = await web3Modal.connect();
const provider = new ethers.providers.Web3Provider(connection);
const signer = provider.getSigner();
const contract = new ethers.Contract(
MarketAddress,
MarketAddressABI,
signer
);
const price = ethers.utils.parseUnits(nft.price.toString(), "ether")
console.log(price)
// code stops here
const transaction = await contract.createMarketSale(nft.tokenId, {
value: price,
});
await transaction.wait();
};
when debugging seems that the code stops before the transaction constant.
when console .log the price I get this:
I tried to remove the toString method, also tried to spread the price object in transaction variable like this value:{...price} but still didn't work

The createMarketSale() first agument expects a BigNumber instance (or a stringified number that it would convert to BigNumber).
When you pass it undefined, it throws the error mentioned in your question.
Solution: Make sure that your nft.tokenId is either a BigNumber or string - not undefined.

Related

Unable to use AWS JS SDK V3 to list all tables

I am following the AWS SDK v3 for Javascript guide to display my DynamoDb table names.
https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html
However, I am receiving the following error. Any help in understanding why I am receiving this error would be greatly appreciated! :-)
TypeError: Cannot read properties of undefined (reading 'ExclusiveStartTableName')
at serializeAws_json1_0ListTablesInput (C:\source\training\react\portfolio-app\finance_api\node_modules\#aws-sdk\client-dynamodb\dist-cjs\protocols\Aws_json1_0.js:3833:19)
at serializeAws_json1_0ListTablesCommand (C:\source\training\react\portfolio-app\finance_api\node_modules\#aws-sdk\client-dynamodb\dist-cjs\protocols\Aws_json1_0.js:357:27)
at serialize (C:\source\training\react\portfolio-app\finance_api\node_modules\#aws-sdk\client-dynamodb\dist-cjs\commands\ListTablesCommand.js:40:72)
at C:\source\training\react\portfolio-app\finance_api\node_modules\#aws-sdk\middleware-serde\dist-cjs\serializerMiddleware.js:12:27
at C:\source\training\react\portfolio-app\finance_api\node_modules\#aws-sdk\middleware-endpoint\dist-cjs\endpointMiddleware.js:20:16
at async C:\source\training\react\portfolio-app\finance_api\node_modules\#aws-sdk\middleware-logger\dist-cjs\loggerMiddleware.js:5:22
at async listTables (file:///C:/source/training/react/portfolio-app/finance_api/src/helper/listAWSTable.js:6:21)
at async file:///C:/source/training/react/portfolio-app/finance_api/src/helper/runAWSCommands.js:4:1
Here are the contents of the javascript file I am using to extract the list of tables, it's basically copied from the developer-guide.
NB I have substituted in my region and I have AWS credentials loaded in my VSCode.
listAWSTables.js
import { DynamoDBClient, ListTablesCommand } from "#aws-sdk/client-dynamodb";
async function listTables() {
const dbclient = new DynamoDBClient({ region: "ap-southeast-2" });
try {
const results = await dbclient.send(new ListTablesCommand());
results.Tables.forEach(function (item, index) {
console.log(item.Name);
});
} catch (err) {
console.error(err);
}
}
export { listTables };
I call it from another file "runAWSCommands.js":
runAWSCommands.js
import { listTables } from "./listAWSTables.js";
await listTables();
At the commandline I start it off using this command: node runAWSCommands.js
The error:
TypeError: Cannot read properties of undefined (reading 'ExclusiveStartTableName')
It is saying: "The ListTablesCommand cannot read a property from an input that is undefined"
If we look at the definition type of ListTablesCommand:
It expects an input value. If we look at the documentation, we can also see an input variable there.
This input object can be empty, in case you don't want to pass any configuration.
Hence, you can change the line:
const results = await dbclient.send(new ListTablesCommand());
to:
const results = await dbclient.send(new ListTablesCommand({}));
And it should work as expected.

Ignore firebase.firestore.timestamp

My project used #Nativescript/firebase(https://github.com/EddyVerbruggen/nativescript-plugin-firebase) ignores methods of firebase.firestore.timestamp, and returns undefined by properties.
The below is minimum reproduction
app.js
import Vue from "nativescript-vue";
import Home from "./components/Home";
var firebase = require("#nativescript/firebase").firebase;
firebase
.init({})
.then(
function () {
console.log("firebase.init done");
},
function (error) {
console.log("firebase.init error: " + error);
}
);
new Vue({
render: (h) => h("frame", [h(Home)]),
}).$start();
Home.vue
import { firebase } from "#nativescript/firebase";
export default {
computed: {
async message() {
const Ref = firebase.firestore
.collection("comments")
.doc("07bhQeWDf3u1j0B4vNwG");
const doc = await Ref.get();
const hoge = doc.data();
console.log("hoge.commented_at", hoge.commented_at); // CONSOLE LOG: hoge.commented_at Sat Oct 23 2021 22:44:48 GMT+0900 (JST)
console.log("hoge.commented_at.seconds", hoge.commented_at.seconds); // CONSOLE LOG: hoge.commented_at.seconds undefined
const hogeToDate = hoge.toDate();
console.log("hogeToDate", hogeToDate); // no console.log appear
return hogeToDate; // simulator shows "object Promise"
},
},
};
I also tried const hogeTimestampNow = firebase.firestore.Timestamp.now(); then no console.log appear...
Environment
vue.js
Node.js v14.17.6
nativescript v8.1.2
nativescript-vue v2.9.0
#nativescript/firebase v11.1.3
If you dive into the source of #nativescript/firebase, in particular looking at /src/firebase-common.ts, you can see that firebase is a custom implementation and not the object/namespace normally exported by the ordinary Firebase Web SDK.
It uses a custom implementation so that it can be transformed depending on the platform the code is running on as shown in /src/firebase.android.ts and /src/firebase.ios.ts.
Of particular importance, is that Firestore's Timestamp objects are internally converted to JavaScript Date objects when exposed to your code as each platform has its own version of a Timestamp object. Because the exposed JavaScript Date object doesn't have a seconds property, you get undefined when attempting to access hoge.commented_at.seconds.
The equivalent of Timestamp#seconds would be Math.floor(hoge.commented_at / 1000) (you could also be more explicit with Math.floor(hoge.commented_at.getTime() / 1000) if you don't like relying on JavaScript's type coercion).
function getSeconds(dt: Date) {
return Math.floor(dt.getTime() / 1000)
}
While you can import the Timestamp object from the Modular Web SDK (v9+), when passed into the NativeScript plugin, it would be turned into an ordinary object (i.e. { seconds: number, nanoseconds: number } rather than a Timestamp).
import { Timestamp } from 'firebase/firestore/lite';
const commentedAtTS = Timestamp.fromDate(hoge.commented_at);
docRef.set({ commentedAt: commentedAtTS.toDate() }) // must turn back to Date object before writing!
firebase.firestore.timestamp does not work via #nativescript/firebase as #samthecodingman said.(https://stackoverflow.com/a/69853638/15966408)
Just use ordinally javascript methods and edit.
I tried
get timestamp from firestore then convert to milliseconds
get date with new Date() then convert to milliseconds
and same miliseconds logged.
via firestore
const Ref = firebase.firestore.collection("comments").doc("07bhQeWDf3u1j0B4vNwG");
const doc = await Ref.get();
const hoge = doc.data();
console.log("hoge.commented_at in milliseconds: ", Math.floor(hoge.commented_at / 1000));
// CONSOLE LOG: hoge.commented_at in milliseconds: 1634996688
via javascript methods
const getNewDate = new Date("October 23, 2021, 22:44:48 GMT+0900");
// same as hoge.commented_at
console.log("getNewDate in milliseconds: ", getNewDate.getTime() / 1000);
// CONSOLE LOG: getNewDate in milliseconds: 1634996688

Property 'subscribe' does not exist on type 'AngularFireList<{}>'

I'm trying to run a chat app using ionic and I'm getting this message
[19:55:51] typescript: src/pages/chat/chat.ts, line: 26
Property 'subscribe' does not exist on type 'AngularFireList<{}>'.
L25: this.username = this.navParams.get('username');
L26: this._chatSubscription = this.db.list('/chat').subscribe( data => {
L27: this.messages = data;
[19:55:51] typescript: src/pages/chat/chat.ts, line: 37
Property 'catch' does not exist on type 'PromiseLike<void>'.
L36: // message is sent
L37: }).catch( () => {
L38: // some error. maybe firebase is unreachable
can anybody help me?
You need to specify valueChanges() or snapshotChanges() before you subscribe.
valueChanges() Returns an Observable of data as a synchronized array of JSON objects. All Snapshot metadata is stripped and just the method provides only the data.
snapshotChanges() Returns an Observable of data as a synchronized
array of AngularFireAction[].
You can read more about retrieving data here
So your code should look like this:
this.db.list('chat').valueChanges().subscribe(data => {
this.messages = data;
});

Sinon stub - Cannot destructure property 'x' of 'undefined' or 'null'

I need to stub the following with Sinon :
const { clientId, dateString } = await parameterParser.prepareInputParameters(con, req);
I have tried using the following:
const retData = {
clientId: 872,
dateString: '1970-01-01',
};
sandbox.stub(parameterParser, 'prepareInputParameters').withArgs(con, req).returns(retData);
but I get the error:
TypeError: Cannot destructure property 'clientId' of 'undefined' or 'null'.
I have successfully stubbed the following elsewhere in my tests:
const { retData } = await sqlFileReader.read('./src/database/sql/getClientIdFromLoanId.sql', [`${req.query.loan_id}`], con, req.logger);
by using:
const retData = {
rowsCount: 1,
rows: [{ client_id: 872 }],
};
sandbox.stub(sqlFileReader, 'read').returns({ retData });
but I cannot get my head round how to stub const { clientId, dateString }
You need to be using resolves instead of returns for these stubs, since you are awaiting their return values, which should actually be Promises that resolve with your retData, and not the retData itself.
In sinon, resolves is a convenience for asynchronous methods. The following two lines are similar:
sinon.stub(foo, 'bar').returns(Promise.resolve('baz'));
sinon.stub(foo, 'bar').resolves('baz');
Your second sample may not be throwing an error, but if you log the value of retData after this line:
const { retData } = await sqlFileReader.read('./src/database/sql/getClientIdFromLoanId.sql', [`${req.query.loan_id}`], con, req.logger);
You'll notice that it is undefined. This is because await causes the result of the method call to be a Promise, which does not have a property called retData.
As for why your first sample is behaving differently, I'm not sure. I suspect that there's something else going on that isn't evident from your samples. Would you mind sharing more code?

Error occurred while parsing your function triggers

The following error is shown while deploying firebase function.
I tried initializing the firebase functions.
I also double-checked the index.js file.
I'm new to deploying firebase functions so please help me for the same.
index.js is as follows:
const functions = require('firebase-functions');
// replaces keywords with emoji in the "text" key of messages
// pushed to /messages
exports.emojify =
functions.database.ref('/messages/{pushId}/text')
.onWrite(event => {
// Database write events include new, modified, or deleted
// database nodes. All three types of events at the specific
// database path trigger this cloud function.
// For this function we only want to emojify new database nodes,
// so we'll first check to exit out of the function early if
// this isn't a new message.
// !event.data.val() is a deleted event
// event.data.previous.val() is a modified event
if (!event.data.val() || event.data.previous.val()) {
console.log("not a new write event");
return;
}
// Now we begin the emoji transformation
console.log("emojifying!");
// Get the value from the 'text' key of the message
const originalText = event.data.val();
const emojifiedText = emojifyText(originalText);
// Return a JavaScript Promise to update the database node
return event.data.ref.set(emojifiedText);
});
// Returns text with keywords replaced by emoji
// Replacing with the regular expression /.../ig does a case-insensitive
// search (i flag) for all occurrences (g flag) in the string
function emojifyText(text) {
var emojifiedText = text;
emojifiedText = emojifiedText.replace(/\blol\b/ig, "😂");
emojifiedText = emojifiedText.replace(/\bcat\b/ig, "😸");
return emojifiedText;
}
Please check the current documentation on triggers, and specifically on migration from Beta to Version 1.0 .
event.data.previous.val() has changed to change.before.val()
event.data.val() has changed to change.after.val()
Also, the Promise statement changes to:
return change.after.ref.parent.child('text').set(emojifiedText);
The complete index.js looks like:
const functions = require('firebase-functions');
// replaces keywords with emoji in the "text" key of messages
// pushed to /messages
exports.emojify=
functions.database.ref('/messages/{pushId}/text')
.onWrite((change,context)=>{
// Database write events include new, modified, or deleted
// database nodes. All three types of events at the specific
// database path trigger this cloud function.
// For this function we only want to emojify new database nodes,
// so we'll first check to exit out of the function early if
// this isn't a new message.
// Only edit data when it is first created.
if (change.before.exists()){
return null;
}
// Exit when the data is deleted.
if (!change.after.exists()){
return null;
}
// Now we begin the emoji transformation
console.log("emojifying!");
//Get the value from the 'text' key of the message
const originalText = change.after.val();
const emojifiedText = emojifyText(originalText);
//Return a JavaScript Promise to update the database nodeName
return change.after.ref.parent.child('text').set(emojifiedText);
});
// Returns text with keywords replaced by emoji
// Replacing with the regular expression /.../ig does a case-insensitive
// search (i flag) for all occurrences (g flag) in the string
function emojifyText(text){
var emojifiedText=text;
emojifiedText=emojifiedText.replace(/\blol\b/ig,"😂");
emojifiedText=emojifiedText.replace(/\bcat\b/ig,"😸");
return emojifiedText;
}

Resources