I'm calling a function using a useEffect. If the data being fetched is an array the function is then parsed (https://github.com/reworkcss/css). However, this is causing the error with mobx. I'm not sure how to fix this.
convertToRule(): void {
var CSS = require('css');
if (this.theme && this.theme.jsonStructure && this.theme.css) {
const stylesheet = JSON.parse(
this.theme.jsonStructure
) as Reptile.Models.IThemesStyling[];
if (Array.isArray(stylesheet)) {
this._rule = CSS.parse(this.theme.css);
} else {
this._rule = stylesheet;
}
}
}
Related
I have a function where I have to return for each "subcontractor" its response for each selection criteria.
Subcontractor object contains a selectionCriteria object. selectionCriteria object contains an array of data for each selectionCriteria a user has responded to.
Each array item is an object, that contains files, id, request (object that contains info about selection criteria user is responding to), response (contains value of the response).
Here is an example of how a subcontractor looks:
This is the function I come up with, but it's quite complex:
const { subcontractors } = useLoaderData<typeof loader>();
const { t } = useTranslation();
const submittedSubcontractors = subcontractors.filter(
(s) => s.status === 'submitted'
);
const subcontractorsResponsesToSelectionCriteria: Array<ISubcontractor> = [];
let providedAnswersResponded: boolean | null = null;
let providedAnswersFiles: Array<IFile> | [] = [];
let providedAnswersRequiresFiles: boolean | null = null;
submittedSubcontractors.forEach((u) => {
u.selectionCriteria.forEach((c) => {
if (c.request.id === criteriaId) {
if (c.response && 'answer' in c.response) {
if (typeof c.response.answer === 'boolean') {
providedAnswersResponded = c.response.answer;
} else {
providedAnswersResponded = null;
}
} else {
providedAnswersResponded = null;
}
providedAnswersFiles = c.files;
providedAnswersRequiresFiles = c.request.are_files_required;
subcontractorsResponsesToSelectionCriteria.push(u as ISubcontractor);
}
});
});
How could I simplify this code by using .reduce() method, or maybe even better ideas?
You should start working on reducing the level of nesting in your if/else like so:
function getProvidedAnswersResponded(response: any) {
if (response && ('answer' in response) && (typeof response.answer === 'boolean')) {
return response.answer;
}
return null;
}
submittedSubcontractors.forEach(u => {
u.selectionCriteria.forEach(c => {
if (c.request.id !== criteriaId) {
return;
}
providedAnswersResponded = getProvidedAnswersResponded(c.response);
providedAnswersFiles = c.files;
providedAnswersRequiresFiles = c.request.are_files_required;
subcontractorsResponsesToSelectionCriteria.push(u);
});
});
The strategy followed was basically to invert the special cases (such as c.requet.id === criteriaId) and exit the function immediately.
Also, extracting the "provided answer responded" function seems atomic enough to move it to a separate block, giving it more verbosity about what that specific code block is doing.
This problem is very annoying. So, I am making a scheduled trigger run every 24 hours. It simply gets items from one collection does some data processing then appends information to another collection. The functioning code works even when the function runs. But it will not let me save because there are "runtime" errors? Even though it was executed perfectly and returned.
Console Error
> result (JavaScript):
EJSON.parse('{"$undefined":true}')
I suppose this has something to do with returning. but when I return null I get this:
> result:
null
> result (JavaScript):
EJSON.parse('null')
when trying to save I get this at the top of the page:
runtime error during function validation
Function Code:
exports = async function() {
const usersCol = context.services.get("SchoologyDashCluster").db("SchoologyDashApp").collection("users");
const gradesCol = context.services.get("SchoologyDashCluster").db("SchoologyDashApp").collection("grades");
var usersCusor = await usersCol.find( ).toArray();
var gradesCusor = await gradesCol.find( ).toArray();
let insert = [];
for (let i = 0; i < usersCusor.length; i++) {
var user = usersCusor[i];
var userSavedGrades = gradesCusor[i].grades
var currentGrades = await getGrades(user.schoologyUID, user.consumerKey, user.secretKey);
var lastGraded = NaN;
let index = gradesCusor[i].grades.length - 1;
while (true) {
if (gradesCusor[i].grades[index].changed == 1) {
lastGraded = index;
break
}
index = index - 1;
}
console.log(lastGraded)
if (userSavedGrades[lastGraded].grades.ga == currentGrades.ga){
currentGrades = { changed : 0, time: new Date().getTime()};
} else {
currentGrades = {changed : 1, grades: currentGrades, time : new Date().getTime()};
}
gradesCol.updateOne(
{"user" : user._id},
{"$push" : {"grades" : currentGrades}}
)
}
// return usersCol.find( );
return null;
};
The answer was simple and now I feel ignorant. Instinctual I put the module imports at the top of the document. However this is incorrect and they need to be placed in the exports function, like so:
exports = function (x,y,z) {
const http = context.http;
return;
}
i want to use useMemo instead of a local state using javascript, react and graphql.
what i am trying to do?
I am displaying a progress bar based on data fetched from progress query. the fetched data from progress query is set in a state.
below is the code,
const ProgressModal = (status) => {
const [progress, setProgress] = React.useState<>(undefined); //progress state
//setting
const { data: progressData, stopPolling: stopPolling } =
useCheckProgressQuery({
variables: {id},
pollInterval: 3000,
})
React.useEffect(() => {
if (status === initial) {
setProgress(undefined);
}
if (status===started) {
setProgress(progressData);
}
if (status === finished && completed >= total || status === failed) {
stopPolling();
setProgress(undefined);
}
}, [progress, progressData, setProgress]);
const completed= progress
? progress.Progress.completed : 0;
const total = progress ? progress.Progress.total : 0;
let value = 0;
if (completed > 0 && total > 0) {
value = (completed / total) * 100;
}
return (
<ProgressBar value = {progress} />
);
}
the above code works but how can i use useMemo for above case instead of a local state. could someone help me with this. i am new to using react hooks. thanks.
useMemo and useState with useEffect do different things, so you can not convert useState/useEffect 100 % equally to useMemo.
A more or less equivalent useMemo approach would be this (but it doesn't work, other refactoring would then also be necessary, see below):
const progress = useMemo(() =>{
if( status === initial ){
return undefined;
}
if( status===started ){
return progressData;
}
if( status === finished && completed >= total || status === failed ){
return undefined);
}
return undefined; // <-- you need to define default/fallback
},
[ progressData, status, completed, total ] // <-- some where missing in your example
);
This is not a working solution, more refactoring is required:
Here e.g. stopPolling() is not called, which needs an extra useEffect now.
progress depends on completed and total, and completed / total both depend on progress (circular dependencies)
here's the code:
loadNextBatch() {
console.log('scrolldown');
this.pageIndex = this.pageIndex + 1;
this.global.getData(`/conditions/latest?start=${this.pageIndex}&length=${this.pageSize}`)
.pipe(take(1)).subscribe(res => {
const newBatch = res['data'];
if (newBatch.length === 0) {
return false;
}
this.tempThermometer.next(this.tempThermometer.getValue().concat(newBatch));
console.log(this.tempThermometer);
});
}
what I'm trying to do here is when there's no data from the /conditions/latest?start=9&length=4 it still running to start=11 ...etc how to make it stop.
when there's no data it should be stop in start=8 because on start=9 there's no data anymore.
How to stop it from the start=8 but when there's a data on start=9 it can be load. but if there's no data on start=9 it shouldn't be loaded.
also the problem when I scroll down it continued to start=11``start=12it should be stop onstart=8cause there's no data onstart=9```
Defined a global variable and wrap the API call in an if condition seems logical right?
canLoadNextbatch = true;
loadNextBatch() {
console.log('scrolldown');
this.pageIndex = this.pageIndex + 1;
if (this.canLoadNextbatch) {
this.global.getData(`/conditions/latest?start=${this.pageIndex}&length=${this.pageSize}`)
.pipe(take(1)).subscribe(res => {
const newBatch = res['data'];
if (newBatch.length === 0) {
this.canLoadNextbatch = false;
} else {
this.tempThermometer.next(this.tempThermometer.getValue().concat(newBatch));
console.log(this.tempThermometer);
}
});
}
}
I'm setting up a searchbar in a web app, and I've got most of it done(i.e. it's successfully finding the objects that I'm looking for), however, a dispatch at the end of the searchbar code. This is being built using Javascript, React and Redux. I'm entirely new to react, and my teams React guy is off for the week, so any help would be a massive help.
searchInList = (e) => {
const { dispatch, employees } = this.props;
const valueSearched = e.target.value;
let currentList = [];
let newList = [];
if (valueSearched !== ' ') {
currentList = employees;
currentList.map(employeeObject => {
Object.values(employeeObject).filter(item => {
let itemString;
if (typeof (item) != 'string') {
itemString = JSON.stringify(item);
} else {
itemString = item;
}
let lc = itemString.toLowerCase();
const filter = valueSearched.toLowerCase();
if (lc.includes(filter)) {
if (!newList.includes(employeeObject)) {
newList.push(employeeObject);
}
}
});
});
} else {
newList = employees;
}
console.log(newList);
dispatch(onChangeEmployee('employees', newList));
};
This should just narrow down the amount of objects being displayed (within the search terms), but it crashes and throws up this error: "TypeError: Cannot set property 'employees' of undefined".
It crashes on the dispatch(onChangeEmployee('employees', newList)); line
From
Cannot set property 'employees' of undefined
I can see you do something like
var a
a.employees='hello'
However, you never refer employees property of an object in the snippet presented
So the chance is high that the error is from onChangeEmployee