setState is not defined - reactjs

I have a print function, it first sets the state of isPrinting to true and open a pring dialog. Once the dialog is being closed it sets the state of isPrinting to false and at this point I'm getting the error (second setState):
Uncaught ReferenceError: setState is not defined
I binded function to current context with the arrow function.
handlePrint = () => {
this.setState({ isPrinting: true }, () => { //setState is working working properly
window.print();
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener = (mql) => {
if (!mql.matches) {
this.setState({ isPrinting: false }); //Error
}
}
}
});
};

I am not sure what you are trying to achieve here but the window.print() freezes the app. There is no code being run unless someone clicks the printing screen away. I works just like window.alert("..."). You can try that by printing a thimestamp right after the win.print. So besides that there is a problem with the this context that cannot be reached the whole function is useless. Because you could just do:
handlePrint = () => {
this.setState({ isPrinting: true }, () => {
window.print() //freezes until someone clicks it away.
this.setState({ isPrinting: false }) //Error
})
}
Regards

Try this.
handlePrint = () => {
let _this = this;
this.setState({ isPrinting: true }, () => {
window.print();
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener = (mql) => {
if (!mql.matches) {
_this.setState({ isPrinting: false });
}
}
}
});
};

This should help
handlePrint = () => {
this.setState({ isPrinting: true }, () => { //setState is working working properly
window.print();
if (window.matchMedia) {
var mediaQueryList = window.matchMedia('print');
mediaQueryList.addListener = (mql) => {
if (!mql.matches) {
return { isPrinting: false };
}
}
}
});
};
setState method should return a new state rather than try to execute anything.

At the second time, instead of setState, just return the new state like:
return {
isPrinting: false,
};

How did you use the function 'mediaQueryList.addListener'?You can console the two 'this' and see if they are same.

Related

Using spread operator to avoid mutating state in React function

In my React project I have a function within a class-based component that handles video uploads. It is working as expected and desired. However, I realized upon inspection that it violates React's don't mutate state mandate. I think that's the case, though I want to ensure that's true, and that the solution I've come up with deals with this.
Here is my component state:
state = {
streamingRes: {},
uploadFailed: false
}
My initial function looked like this (notice there are 3 places where I am setting the state):
fileUploadHandler = (id, file, fileId) => {
const isValid = this.validateVideoFileType(file);
if(!isValid) this.props.showError(`${file.name} is of the wrong file type (${file.type}). File must be an acceptable video format.`);
let dataStream = io.Stream.createStream();
io.Socket.on('userVideos.uploadProgress', (data) => {
this.setState( { streamingRes: data });
if(fileId === data.data.guid) {
this.uploadCompletionPercentage = data.data.progress;
}
});
io.Stream(io.Socket).emit('userVideos.upload', dataStream, {
guid: fileId,
size: file.size
}, (data) => {
if(data.status === "failure") {
this.props.onUploadFailed();
this.setState( { uploadFailed: true })
}
else if(data.status === "success") {
this.props.upload(id)
}
});
this.setState( { uploadFailed: false });
io.Stream.createBlobReadStream(file).pipe(dataStream);
return;
}
To avoid mutating state I updated this function to look like this:
handleFileUpload = (id, file, fileId) => {
let newState = {...this.state};
const isValid = this.validateVideoFileType(file);
if(!isValid) this.props.showError(`${file.name} is of the wrong file type (${file.type}). File must be an acceptable video format.`);
let dataStream = io.Stream.createStream();
io.Socket.on('userVideos.uploadProgress', (data) => {
this.setState( { streamingRes: data });
if(fileId === data.data.guid) {
this.uploadCompletionPercentage = data.data.progress;
}
});
io.Stream(io.Socket).emit('userVideos.upload', dataStream, {
guid: fileId,
size: file.size
}, (data) => {
if(data.status === "failure") {
this.props.onUploadFailed();
newState.uploadFailed = true;
this.setState( { uploadFailed: newState.uploadFailed });
}
else if(data.status === "success") {
this.props.upload(id)
}
});
newState.uploadFailed = false;
this.setState( { uploadFailed: newState.uploadFailed });
io.Stream.createBlobReadStream(file).pipe(dataStream);
return;
}
Notice I am using the spread operator right at the top of the function now. My question is: does this effectively deal with the issue of avoiding state mutation?
Yes, you have avoided mutating state. However, your way of doing it is completely unnecessary because there is no need to copy the state into a new object if you don't use that object.
Instead of:
newState.uploadFailed = true;
this.setState( { uploadFailed: newState.uploadFailed });
You can simply do:
this.setState({ uploadFailed: false });
There was no problem in your code in the first place.

Why can't I access and setState here?

I have this handle change function. I cannot figure out why in the timeout section, I cannot access this.state? It works if I do it outside of that?
The part where i'm trying to setState employment_level gives me an 'undefined' error.
The console log console.log(${targetName}: ${targetValue}); works perfecly... but the two that reference this.state.empoloyee and this.state.employment_level do not.
handleChange = e => {
const targetName = e.target.name;
const targetValue = e.target.value;
this.setState({
[targetName]: targetValue,
});
if (this.state.editingTimeout) {
clearTimeout(this.state.editingTimeout);
}
this.setState({
editing: false,
editingTimeout: setTimeout(function () {
console.log(`${targetName}: ${targetValue}`);
this.setState({
employment_level: targetValue,
});
console.log(this.state.employee);
console.log(this.state.employment_level);
}, 300),
});
}
Maybe it works if you use an arrow functions in:
editingTimeout: setTimeout(() =>

SetState is not working and giving the error of undefined in react

I have a below snippet.
private hideFormAccess = () => {
this.setState(
{
isFormAccess: false
}
);
};
This is giving error of setstate not defined but when i modified it
private hideFormAccess = () => {
this.setState(
{
isFormAccess: false
},
() => {
// console.log('Test');
}
);
};
Now its working fine, but problem is that in call back i don't want any function to call (Where right now i mention the console.log).
Is there any other way to resolve this issue.

simulate change not working with trim() enzyme

I was using this test when I had a bug, so I used the trim function for resolve it, and the these test fail, tried in different ways but didn't found the solution
const generalWrapper = shallow(<AddVehiclesTable {...generalProps} />)
const generalInstance = generalWrapper.instance()
describe('onSearchChange', () => {
test('should change the "search" state', () => {
const theFilterValue = 'a new filter value'
generalWrapper.find('.filter-input').simulate('change', { target: { value: theFilterValue } })
const expectedState = Object.assign({}, generalInstance.state)
expectedState.searchValue = { 'target': { 'value': theFilterValue } }
expect(generalInstance.state).toEqual(expectedState)
expect(generalInstance.state.userInteractedWithComponent).toBe(true)
})
})
onSearchChange (searchValue) {
const value = searchValue.trim()
this.setState({ searchValue: value, userInteractedWithComponent: true })
}
Error message
TypeError: searchValue.trim is not a function
Any suggestions
Your function gets the Object as a parameter.
Expose field that you needed
I don't see the whole picture, but can guess that you need something like
onSearchChange ({ target: { value: incomeValue } }) {
const value = incomeValue.trim()
this.setState({ searchValue: value, userInteractedWithComponent: true })
}

Unit test for a function calling another function using jest

I'm new to Jest and having some issues to write the unit test.
My function is calling another anonymous function with some parameters.
Could you please help me fix it?
const myFunctionToTest = (code, data) => (isValid, availableCodes, defaultValue) => {
if(isValid) {
const isAvailableCode = isEmpty(availableCodes) || includes(availableCodes, code);
return isAvailableCode ? get(data, 'originalQty') : defaultValue;
}
return defaultValue;
};
Here's the mock data:
Mock data:
code: 'AB'
data: { originalQty : 2 };
isValid: true;
availableCodes: ['BCD', 'AB'];
defaultValue: 0;
What I tried!
describe('myFunctionToTest', () => {
test('it should return originally assigned quantity', () => {
const result = myFunctionToTest('AB', { originalQty: 2 } , () => {true, ['BCD', 'AB'], 0});
expect(result).toEqual(2);
});
});
Ok, I got it.
This is what I tried!
describe('myFunctionToTest', () => {
test('it should return originally assigned quantity', () => {
const result = myFunctionToTest('AB', { originalQty: 2 });
expect(result(true, ['BCD', 'AB'], 0).toEqual(2);
});
});

Resources