React component with async array not updating [duplicate] - javascript

This question already has answers here:
Why am i getting and empty array when fetching an api with react hooks?
(4 answers)
Closed 13 days ago.
I have a component that gets an array of objects from a database using an async - await function. When the function gets the data and sets the array to a State variable, the component doesn't seem to update and I get errors about being unable to read properties. The data is being retrieved from the database correctly because I can console.log it. What am I doing wrong?
export default function LevelLeaderboard ({ level }) {
const [leaderboardData, setLeaderboardData] = useState([])
useEffect(()=>{
getLeaderBoardData(level)
.then((data)=>{
console.log(data)
setLeaderboardData(data)
})
},[level]);
return (
<div id="level" className="level-leaderboard">
<ul>
<li>{leaderboardData[0]['name']}</li>
</ul>
</div>
)
}
Error:
LevelLeaderboard.js:19 Uncaught TypeError: Cannot read properties of undefined (reading '0')
at LevelLeaderboard (LevelLeaderboard.js:19:1)
at renderWithHooks (react-dom.development.js:16305:1)
at mountIndeterminateComponent (react-dom.development.js:20074:1)
at beginWork (react-dom.development.js:21587:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at beginWork$1 (react-dom.development.js:27451:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
Here's the async function:
export async function getLeaderBoardData(level, handleData){
const querySnapshot = await getDocs(collection(leaderboard, level));
let tempArr = [];
querySnapshot.forEach((doc) => {
tempArr.push(doc.data())
});
return tempArr;
}

You should add a conditional rendering to
<li>{leaderboardData[0]['name']}</li>
something like:
{leaderboardData.length >= 1 && <li>{leaderboardData[0]['name']}</li>}
since the array 'leaderboardData' its empty when component first render

Related

mapping but getting error Uncaught TypeError: dataList.map is not a function

Hello i have a MERN project, this is my first time using mongodb. So i want to get the data by id and map the data. but i kept getting error like this
Uncaught TypeError: dataList.map is not a function
at HistoryDetail (HistoryDetail.js:216:1)
at renderWithHooks (react-dom.development.js:16305:1)
at updateFunctionComponent (react-dom.development.js:19588:1)
at beginWork (react-dom.development.js:21601:1)
at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
at invokeGuardedCallback (react-dom.development.js:4277:1)
at beginWork$1 (react-dom.development.js:27451:1)
at performUnitOfWork (react-dom.development.js:26557:1)
at workLoopSync (react-dom.development.js:26466:1)
the data is fine in the console and network. Is this the problem with how i mapping the data or wrong format ? idk.
this is the data in console and network :
https://cdn.discordapp.com/attachments/755260290450587661/1025606524099383326/unknown.png
https://cdn.discordapp.com/attachments/755260290450587661/1025606569896988682/unknown.png
this is the front end code :
const [ dataList, setDataList ] = useState([]);
const getData = () => {
Axios.get(`http://localhost:3001/registration/${id}`).then((response) => {
console.log(response.data)
setDataList(response.data)
});
};
useEffect(() => {
userExpire();
getData();
}, [])
<div className='flexbox-container'>
<div className='flexbox-item flexbox-item-1'>
{dataList.map((val, index) => {
return (
<div className="leftDiv" key={index}>
<h2 className='textSupplier'>Supplier Data</h2>
<div className='textData'>
<p>Company Name : {val.CompanyName}</p>
<p>Address: {val.Address}</p>
<p>Phone Number : {val.PhoneNumber}</p>
<p>President Director (Name) : {val.PresidentName}</p>
<p>Account Manager (Email / Phone) : {val.AccountManagerEmail} / {val.AccountManagerPhone}</p>
<p>Escalation PIC (Email / Phone) : {val.PICEmail} / {val.PICPhone}</p>
<p>Established Date : {moment(val.EstablishedDate).format("DD MMMM YYYY")} </p>
<p>Main Business : {val.MainBusiness}</p>
<p>Employee Number : {val.EmployeeNumber}</p>
<p>Number of Customer : {val.NumberOfCustomer}</p>
<p>Attachments : {val.Attachments}</p>
<p>ID : {val._id}</p>
</div>
</div>
)})}
</div>
backend :
app.get("/registration/:id", (req, res) => {
const Id = req.params.id;
DataModel.findById({_id : Id}, (err, result) => {
if (err) {
res.send(err)
}else {
res.send(result)
}
})
});

Passing in list elements in javascript to a different function

I'm trying to do a web scraping exercise where some values are being retrieved and are being stored in a list variable. I am then passing in the list variable as a parameter in a different function. The problem with my approach is I am getting an error when calling the different function. I believe I'm getting this error because I am not passing in the list elements into the function appropriately. In the function, I am reading from a Yahoo Stock API used to retrieve stock data. If I were to hardcode a stock symbol into the parameter for the function, it works without any issue. Since I am passing in a parameter, I am getting this error. Below is my code and the error I am getting. Any feedback would be helpful.
Code
const cheerio = require('cheerio');
const axios = require('axios');
const yahooStockPrices = require('yahoo-stock-prices');
var stockSymbol = []
async function read_fortune_500() {
try {
const { data } = await axios({ method: "GET", url: "https://en.wikipedia.org/wiki/List_of_S%26P_500_companies", })
const $ = cheerio.load(data)
const elemSelector = '#constituents > tbody > tr > td:nth-child(1)'
$(elemSelector).each((parentIndex, parentElem) => {
let keyIndex = 0
if (parentIndex <= 9){
$(parentElem).children().each((childIndex, childElem) => {
const tdValue = $(childElem).text()
if (tdValue) {
//stockObject[keys[keyIndex]] = tdValue
stockSymbol = tdValue
}
})
console.log(stockSymbol)
}
})
} catch (err) {
console.error(err)
}
return stockSymbol;
}
async function collect_stocks(stockSymbol) {
stockSymbol = read_fortune_500()
const stockResult = await yahooStockPrices.getCurrentData(stockSymbol);
console.log(stockResult);
}
collect_stocks(stockSymbol)
Error
/node_modules/yahoo-stock-prices/yahoo-stock-prices.js:75
.split('regularMarketPrice')[1]
^
TypeError: Cannot read properties of undefined (reading 'split')
at Request._callback (/node_modules/yahoo-stock-prices/yahoo-stock-prices.js:75:21)
at Request.self.callback (/node_modules/request/request.js:185:22)
at Request.emit (node:events:390:28)
at Request.emit (node:domain:475:12)
at Request.<anonymous> (/node_modules/request/request.js:1154:10)
at Request.emit (node:events:390:28)
at Request.emit (node:domain:475:12)
at IncomingMessage.<anonymous> (/node_modules/request/request.js:1076:12)
at Object.onceWrapper (node:events:509:28)
at IncomingMessage.emit (node:events:402:35)
The parameter stockSymbol seems to be empty when you pass it to your desired function therefore, when yahoo-stock-prices try to apply a split on it, it fails.

Error when trying to upload images to Firebase storage

I am trying to create an app which allow the user to upload an image and display it in the page with React and Firebase.
this is the part of the code that responsible for the issue:
the image variable is coming from from the state
const [image, setImage] = useState("");
const [caption, setCaption] = useState("");
const [progress, setProgress] = useState(0)
function handleChange (e){
if (e.target.files[0]){
setImage(e.target.files[0]);
}
}
function handleUpload(){
const uploadTask = storage.ref('images/${image.name}').put(image)
uploadTask.on(
"state_changed",
(snapshot) => {
const progress = Math.round(
(snapshot.bytesTransferred / snapshot.totalBytes) * 100
);
setProgress(progress);
},
(error) => {
console.log(error);
alert(error.message);
},
() => {
storage
.ref("images")
.child(image.name)
.getDownloadURL()
.then(url => {
db.collection("posts").add({
timestamp: db.FieldValue.serverTimestamp(),
caption : caption,
imgUrl: url,
userName: username
})
setProgress(0);
setCaption("");
setImage(null);
})
}
)
}
and this error get logged in the console :
Uncaught
FirebaseStorageErrorĀ {code_: "storage/invalid-argument", message_: "Firebase Storage: Invalid argument in `put` at index 0: Expected Blob or File.", serverResponse_: null, name_: "FirebaseError"}code_: "storage/invalid-argument"message_: "Firebase Storage: Invalid argument in `put` at index 0: Expected Blob or File."name_: "FirebaseError"serverResponse_: nullcode: (...)message: (...)name: (...)serverResponse: (...)__proto__: Object
rethrowCaughtError # react-dom.development.js:328
runEventsInBatch # react-dom.development.js:3336
runExtractedPluginEventsInBatch # react-dom.development.js:3537
handleTopLevel # react-dom.development.js:3581
batchedEventUpdates$1 # react-dom.development.js:21729
batchedEventUpdates # react-dom.development.js:798
dispatchEventForLegacyPluginEventSystem # react-dom.development.js:3591
attemptToDispatchEvent # react-dom.development.js:4311
dispatchEvent # react-dom.development.js:4232
unstable_runWithPriority # scheduler.development.js:659
runWithPriority$1 # react-dom.development.js:11077
discreteUpdates$1 # react-dom.development.js:21746
discreteUpdates # react-dom.development.js:811
dispatchDiscreteEvent # react-dom.development.js:4211
I have tried to change put(image) to put(blob) but it did not work
The line:
const uploadTask = storage.ref('images/${image.name}').put(image)
Has an error, it should be using the symbol ` (backquote/backtick) instead of using single quotes ':
const uploadTask = storage.ref(`images/${image.name}`).put(image)
otherwise you will create a reference to the literal string images/${image.name} instead of image/value_of_variable_image.jpg more about Template literals can be found here
You haven't still showed us what's the content of the image variable, I can see from the code that you're calling a setState inside a function that appears to be a callback, but I'm not seeing from where are you calling, you can do it from a input like this:
<input type="file" onChange={handleChange} />
If you're already using it like that, I recommend to add console.log(image) outside of a function in order debug what's the content of the variable before sending it to put(). Just as a reference the output from the console.log(image) should be an instance of the File javascript API

Unable to use web3.eth.accounts.wallet.encrypt

I am trying to create a metamask like a wallet using web3. I am using React for the front end.
I am able to create a wallet but I am getting an error for encrypt function.
Following is the code I am using inside a React Component:-
handleClick = async (event) => {
try {
event.preventDefault();
const web3 = new Web3();
const account = web3.eth.accounts.create();
console.log(account);
const wallet = web3.eth.accounts.wallet.create();
wallet.defaultKeyName = this.state.accountName;
wallet.add(account.privateKey);
console.log(wallet);
const encryptedWallet = web3.eth.accounts.wallet.encrypt(this.state.password);
console.log(encryptedWallet);
}
catch (error) {
console.log(error);
}
}
Following is the error:-
TypeError: "list" argument must be an Array of Buffers
at Function.concat (index.js:399)
at Accounts.push../node_modules/web3-eth-accounts/src/index.js.Accounts.encrypt (index.js:431)
at Object.encrypt (index.js:111)
at index.js:548
at Array.map (<anonymous>)
at Wallet.push../node_modules/web3-eth-accounts/src/index.js.Wallet.encrypt (index.js:547)
at CreateWallet.handleClick (CreateWallet.js:46)
at HTMLUnknownElement.callCallback (react-dom.development.js:188)
at Object.invokeGuardedCallbackDev (react-dom.development.js:237)
at invokeGuardedCallback (react-dom.development.js:292)
at invokeGuardedCallbackAndCatchFirstError (react-dom.development.js:306)
at executeDispatch (react-dom.development.js:389)
at executeDispatchesInOrder (react-dom.development.js:414)
at executeDispatchesAndRelease (react-dom.development.js:3278)
at executeDispatchesAndReleaseTopLevel (react-dom.development.js:3287)
at forEachAccumulated (react-dom.development.js:3259)
at runEventsInBatch (react-dom.development.js:3304)
at runExtractedPluginEventsInBatch (react-dom.development.js:3514)
at handleTopLevel (react-dom.development.js:3558)
at batchedEventUpdates$1 (react-dom.development.js:21871)
at batchedEventUpdates (react-dom.development.js:795)
at dispatchEventForLegacyPluginEventSystem (react-dom.development.js:3568)
at attemptToDispatchEvent (react-dom.development.js:4267)
at dispatchEvent (react-dom.development.js:4189)
at unstable_runWithPriority (scheduler.development.js:653)
at runWithPriority$1 (react-dom.development.js:11039)
at discreteUpdates$1 (react-dom.development.js:21887)
at discreteUpdates (react-dom.development.js:806)
at dispatchDiscreteEvent (react-dom.development.js:4168)
Complete code is available at https://github.com/samarth9201/crypto-wallet.git.
I don't know if I am using it the incorrect way.

How to Retrieve individual JSON values from Firebase Database?

Let's say I have a firebase node that is dbref = firebase.ref('/Transfer_Request/{pushID]/').
And the client writes two values; from_ID and to_ID to dbref. How do I get the individual values of the from_ID and to_ID from Firebase Cloud functions?
My code:
exports.TransferTicket = functions.database.ref('/Transfer_Request/{pushID}').onWrite((event) => {
const original = event.data.val();
const from_ID = original.from_ID;
const to_email_ID = original.to_ID;
//search for to_email ID
return admin.database().set("A transfer request was just made");
});
I'm getting two errors:
1)
TypeError: admin.database(...).set is not a function at
exports.TransferTicket.functions.database.ref.onWrite
(/user_code/index.js:41:25) at Object.
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native) at
/user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:716:24 at process._tickDomainCallback
(internal/process/next_tick.js:135:7)
2)
TypeError: Cannot read property 'from' of null at
exports.TransferTicket.functions.database.ref.onWrite
(/user_code/index.js:35:25) at Object.
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:59:27)
at next (native) at
/user_code/node_modules/firebase-functions/lib/cloud-functions.js:28:71
at __awaiter
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:24:12)
at cloudFunction
(/user_code/node_modules/firebase-functions/lib/cloud-functions.js:53:36)
at /var/tmp/worker/worker.js:716:24 at process._tickDomainCallback
(internal/process/next_tick.js:135:7)
The first problem comes from the fact that when doing the following you miss a Firebase Reference.
return admin.database().set("A transfer request was just made");
You should do:
admin.database().ref('...the path where you want to write...').set("A transfer request was just made");
For more details, see the doc for Reference and Database .
The second problem comes from the fact that since the new release of the version 1.0.0 of the Firebase SDK for Cloud Functions, the syntax has changed. See this doc item.
You should modify your code as follows:
exports.TransferTicket = functions.database.ref('/Transfer_Request/{pushID}').onWrite((change, context) => {
const original = change.after.val();
const from_ID = original.from_ID;
console.log(from_ID);
const to_email_ID = original.to_ID;
console.log(to_email_ID);
return admin.database().ref('...path...').set("A transfer request was just made")
.catch(error => {
console.log(error);
//...
});
});

Categories

Resources