I'm passing arguments into my render() function the following way:
render() {
const { minerid, ownerid, logs, address } = this.props.miner
}
They are structured like so:
Sometimes, the script that is sending these logs crashes.
I have tried making this handler in order to add logs full of zeroes to the log array.
handleCrash = (logs) => {
let time = parseFloat(logs[logs.length - 1].time)
const newTime = Date.now()
const num = logs[logs.length - 1].gpus.num
if ((newTime - time) > 300) {
time = time+300
logs.push(
{
gpus: {
fans: Array(num).fill('0'),
hashrate: Array(num).fill('0'),
temps: Array(num).fill('0'),
num: num
},
miner: logs[logs.length - 1].miner,
time: time
}
)
}
}
I have then tried putting this in my componentDidMount() :
componentDidMount () {
this.handleCrash(this.props.miner.logs)
}
as well as putting handleCrash() in my render method like this:
render() {
this.handleCrash(this.props.miner.logs)
const { minerid, ownerid, logs, address } = this.props.miner
I have different functions manipulating this data calculating averages and graphing charts further down into the app.
They all work fine until I try to add these zero logs and I get "Error: <path> attribute d: Expected number, "MNaN,85.926498958…" and the graphs don't render anymore.
The zero logs look like they are the exact same structure as all the other logs.
Anyobody knows what am I doing wrong here? Thank you in advance!
Maybe something like this:
handleCrash = (logs) => {
let time = parseFloat(logs[logs.length - 1].time)
const newTime = Date.now()
const num = logs[logs.length - 1].gpus.num
if ((newTime - time) > 300) {
time = time+300
logs.push(
{
gpus: {
fans: Array(num).fill('0'),
hashrate: Array(num).fill('0'),
temps: Array(num).fill('0'),
num: num
},
miner: logs[logs.length - 1].miner,
time: time
}
)
}
return logs
}
render() {
const { minerid, ownerid, logs, address } = this.handleCrash(this.props.miner.logs)
Related
The whole process looks more or less this way:
const response = {};
let st;
const queryString = 'abe433,32a8b7,ede8a4,1ba48c';
const keysToProcess = queryString.split(',');
keysToProcess.map((keyToProcess) => {
st = keyToProcess.toUpperCase();
response[keyToProcess] = { st };
});
Now, the code above run in a browser console yields something like this, when calling JSON.stringify(response);:
'{"abe433":{"st":"ABE433"},"32a8b7":{"st":"32A8B7"},"ede8a4":{"st":"EDE8A4"},"1ba48c":{"st":"1BA48C"}}'
However, when run in an Express.js app, I find things like this logged to the console:
{
abe433: {
'st': 'ABE433'
},
'32a8b7': {
'st': '32A8B7'
},
ede8a4: {
'st': 'EDE8A4'
},
'1ba48c': {
'st': 'BA48C'
}
}
When I tried to stringify keys doing response[JSON.stringify(keyToProcess)] = { st }, I ended up with keys like '"ede8a4"'.
How should I ensure the keys are stored as strings?
I used aws-sns to create one webhook. Two lambda functions are checked by this webhook. One of the lambda functions publishes 'orderId' and'startTime', while another publishes 'orderId' and 'roundName'. Both lambdas fire at different times. As a result, publishing can happen at two different times. One or both of the'startTime' and 'roundName' parameters may be undefined.
If 'roundName' exists, the 'updateOrder' variable will return 'roundName,' and the database will be updated. When'startTime' is set and 'roundName' is left blank, the 'roundName' will be rewritten from the database, which I don't want. Because if there is a 'roundName,' there will always be a 'roundName,' the value of 'roundName' can change but it will never be undefined.If startTime changes as well as roundName change then it will update the database. But my current logic is wrong. Struggling to implementing diffrent scenario logic.
const data = {
Records: [
{
Sns: {
Message:
'[{\n "orderId": "a4013438-926f-4fdc-8f6a-a7aa402b40ea",\n "roundName": "RO1"}]',
},
},
],
};
const existingData = [
{
modifiedAt: "2022-03-09T13:18:06.211Z",
lastMile: "progress",
createdAt: "2022-02-26T06:38:50.967+00:00",
orderId: "a4013438-926f-4fdc-8f6a-a7aa402b40ea",
},
];
// parse the data
const parseData = data.Records.flatMap((record) =>
JSON.parse(record.Sns.Message)
);
// check if the data exist or not
const existingOrder = existingData.filter(
(o1) => parseData.some((o2) => o1.orderId === o2.orderId)
);
// if there is no existingOrder then return false
if (existingOrder.length === 0) return;
// if there is exisiting order then add roundName and startTime from SNS event
const updateOrder = existingOrder.map((i) => {
const roundName = parseData.find((r) => {
return r.orderId === i.orderId;
}).roundName;
const startTime = parseData.find((r) => {
return r.orderId === i.orderId;
}).startTime;
return {
roundName: roundName ?? "",
startTime: startTime ?? "",
};
});
console.log(updateOrder);
I have to introduce pagination in findAll() method. I really dont know how to do it. I tried but it is giving so many errors. I used findAndCount() method given by typeorm for that, But I am not sure how it will work.
As of now below method returning all the record. I need to return at a time 10 records. Please suggest what modification I need to do.
async findAll(queryCertificateDto: QueryCertificateDto,page=1): Promise<PaginatedResult> {
let { country, sponser } = queryCertificateDto;
const query = this.certificateRepository.createQueryBuilder('certificate');
if (sponser) {
sponser = sponser.toUpperCase();
query.andWhere('Upper(certificate.sponser)=:sponser', { sponser });
}
if (country) {
country = country.toUpperCase();
query.andWhere('Upper(certificate.country)=:country', { country });
}
const certificates = query.getMany();
return certificates;
}
this is PaginatedResult file.
export class PaginatedResult {
data: any[];
meta: {
total: number;
page: number;
last_page: number;
};
}
I tried changing code of findAll() but where clause is giving error. I am not sure how to handle query.getMany() in pagination.
const take = query.take || 10
const skip = query.skip || 0
const [result, total] = await this.certificateRepository.findAndCount(
{
where: query.getMany(), //this is giving error
take:take,
skip:skip
}
);
return result;
I need to introduce pagination in this method. Any help will be really helpful.
Typeorm has a really nice method specific to your usecase findAndCount
async findAll(queryCertificateDto: QueryCertificateDto): Promise<PaginatedResult> {
const take = queryCertificateDto.take || 10
const skip = queryCertificateDto.skip || 0
const country = queryCertificateDto.keyword || ''
const sponser = queryCertificateDto.sponser || ''
const query = this.certificateRepository.createQueryBuilder('certificate');
const [result, total] = await this.certificateRepository.findAndCount(
{
where: { country: Like('%' + country + '%') AND sponser: Like('%' + sponser + '%') }, order: { name: "DESC" },
take: take,
skip: skip
}
);
return {
data: result,
count: total
};
}
More documentation about Repository class can be found here
You don't need the .getMany() with your where in the last code, the result is an array of the data you need.
From your first code, you can do this:
async findAll(queryCertificateDto: QueryCertificateDto,page=1): Promise<PaginatedResult> {
// let's say limit and offset are passed here too
let { country, sponser, limit, offset } = queryCertificateDto;
const query = this.certificateRepository.createQueryBuilder('certificate');
if (sponser) {
sponser = sponser.toUpperCase();
query.andWhere('certificate.sponser = :sponser', { sponser });
}
if (country) {
country = country.toUpperCase();
query.andWhere('certificate.country = :country', { country });
}
// limit and take mean the same thing, while skip and offset mean the same thing
const certificates = await query
.orderBy("certificate.id", "ASC")
.limit(limit || 10)
.offset(offset || 0)
.getMany();
// if you want to count just replace the `.getMany()` with `.getManyandCount()`;
return certificates;
}```
I'm new to JavaScript and React and am trying to move away from tutorials so have started making a simple app for my own learning benefit but have run into a roadblock with functions running asynchronously.
In onSearchSubmit, there is a setState which has the following in its callback:
this.findSalaryRangeMin(data.advertiser.id, data.teaser);
this.findSalaryRangeMax(data.advertiser.id, data.teaser);
How can I get these two functions above to run synchronously? findSalaryRangeMax uses this.state.salaryLower which is set in findSalaryRangeMin, but the console.log below reveals that findSalaryRangeMax is firing before findSalaryRangeMin has completed.
findSalaryRangeMax = (advertiserId, teaser) => {
console.log(`this.state.salaryLower: `, this.state.salaryLower);
// ... More code
};
I've read some resources which mention using promises, but I wasn't able to figure out how to apply it... I also am wondering whether it can be achieved with async/await.
Full(ish) Code:
(I've removed some code for simplicity)
import React from "react";
import JobSearch from "../api/jobSearch"; // axios
import SearchBar from "./SearchBar";
class App extends React.Component {
state = {
jobTitle: "",
advertiser: "",
salaryLower: "",
salaryLowerTop: "",
salaryUpper: "",
salaryUpperTop: ""
};
findSalaryRangeMin = (advertiserId, teaser) => {
this.setState({ salaryLower: 0, salaryLowerTop: 200000 }, async () => {
let salaryLowerPrev;
for (var i = 0; i < 20; i++) {
const response = await JobSearch.get(
`http://localhost:3001/salary-range/${advertiserId}/${this.state.salaryLower}/${this.state.salaryLowerTop}/${teaser}`
);
console.log(response);
if (response.data.totalCount === 1) {
salaryLowerPrev = this.state.salaryLowerTop;
this.setState({
salaryLowerTop: Math.round(
(this.state.salaryLowerTop - this.state.salaryLower) / 2 +
this.state.salaryLower
)
});
} else {
this.setState(
{
salaryLowerTop: salaryLowerPrev
},
() => {
this.setState({
salaryLower: Math.round(
(this.state.salaryLowerTop - this.state.salaryLower) / 2 +
this.state.salaryLower
)
});
}
);
}
}
});
};
findSalaryRangeMax = (advertiserId, teaser) => {
console.log(`this.state.salaryLower: `, this.state.salaryLower);
// ... More code
};
onSearchSubmit = async term => {
const response = await JobSearch.get(
`http://localhost:3001/job-info/${term}`
);
if (response.data.totalCount === 1) {
const data = response.data.data[0];
this.setState(
{
jobTitle: data.title,
advertiser: data.advertiser.description
},
() => {
this.findSalaryRangeMin(data.advertiser.id, data.teaser);
this.findSalaryRangeMax(data.advertiser.id, data.teaser);
}
);
} else {
console.log("totalCount not equal to 1: ", response.data.totalCount);
}
};
render() {
return (
<div>
<SearchBar onSearchSubmit={this.onSearchSubmit} />
<hr />
<div>
Job Title: {this.state.jobTitle}
Advertiser: {this.state.advertiser}
Salary Lower Range: {this.state.salaryLower}
Salary Upper Range: {this.state.salaryUpper}
</div>
</div>
);
}
}
export default App;
To give some context, the app I'm trying to make, queries an API for a jobs listing site. The API response doesn't reveal a salary range for an individual job, but the salary can fairly accurately be determined by querying salary ranges.
You are correct in your understanding that async or promises are needed if you want the functions to run synchronously and the existing code will run to the following line findSalaryRangeMax before returning with the data needed.
async/await and promises will definitely help, but often it's worth considering a few code changes too. As an example, you could combine the two functions into a single function like
findSalaryRanges(data.advertiser.id, data.teaser)
and fetch the data, process and set state once.
some pseudo code:
findSalaryRanges = async () => {
// get all the data needed first
const maxSalaryData = await JobSearch.get(`http://localhost:3001/salary-range/${advertiserId}/${this.state.salaryLower}/${this.state.salaryLowerTop}/${teaser}`);
const minSalaryData = await JobSearch.get(...);
// process data as needed
...
// set state once
this.setState({
salaryTop: salaryTop,
salaryLower: salaryLower
});
};
setState is async, so if you are dependent on the value of the state before running the next function you could do something like:
this.setState({
salaryLowerTop: Math.round(
(this.state.salaryLowerTop - this.state.salaryLower) / 2 +
this.state.salaryLower
)
}, () => this.findSalaryRangeMax(data.advertiser.id, data.teaser))
Can I execute a function after setState is finished updating?
I have a component that will basically serve as a fully self-contained file being uploaded. For the time being, until I get the upload mechanism in place, I'm just using a timer to simulate a progress change. However, when it hits 100% and tries to send a message to its parent (via statusChange), I've got a scoping issue where this is referring to window. How can I fix this?
The actual error:
Uncaught TypeError: _this.props.statusChange is not a function
componentDidMount() {
this.timer = setInterval(() => {
this.setState({progress: this.state.progress + 5});
if (this.state.progress === 100) {
clearInterval(this.timer);
this.props.statusChange({uploadComplete: true});
}
}, 1000);
debugMode && console.info('[FileUpload] Began uploading %s',
this.props.name);
},
EDIT:
The problem seems to be in the passing of the callback. this.props.statusChange is indeed null the entire time.
Ahhh, damn! It was a scoping issue here. I'll highlight it below:
UploadQueue = React.createClass({
displayName: 'UploadQueue',
propTypes: {
fileList: React.PropTypes.any.isRequired
},
statusChange(status) {
debugMode && console.info('[UploadQueue] Status change! %o', status);
},
render() {
let files = [];
// Convert to a true array
for (let i = 0; i < this.props.fileList.length; ++i) {
files = files.concat(this.props.fileList[i]);
}
return (
<div>
{files.map(function (file) { // should be: {files.map(file => {
return <FileUpload key={file.name}
name={file.name}
statusChange={this.statusChange} />
})}
</div>
)
}
});
this scoping issue was in the component that owns FileUpload. Fixed code below.
{files.map(file => {
return <FileUpload key={file.name}
name={file.name}
statusChange={this.statusChange} />
})}
try this:
componentDidMount() {
this.timer = setInterval(() => {
this.setState({progress: this.state.progress + 5});
if (this.state.progress === 100) {
clearInterval(this.timer);
this.props.statusChange({uploadComplete: true});
}
}.bind(this), 1000);
^^^^^^^^^^^^
debugMode && console.info('[FileUpload] Began uploading %s',
this.props.name);
},