React functional components- say its not a function - javascript

i am using react functional components (infact learning hooks ), so i am facing one issue when calling a function with in another function
here is my code
my functional component
const LiteraryPage = props => {
if (Object.keys(mainData).length === 0 && mainData.constructor === Object) {
setMainDataSection(validateData(mainData));
}
const validateData = async (data) => {
let finalDataArray = [];
if (data.cars !== undefined) {
finalDataArray = finalDataArray.concat(data.cars);
}
if (data.mobiles !== undefined) {
finalDataArray = finalDataArray.concat(data.mobiles);
}
if (data.scooters !== undefined) {
finalDataArray = finalDataArray.concat(data.scooters);
}
return finalDataArray;
};
}
But am getting a error
Uncaught TypeError: validateData is not a function
Please correct me if am missing something or if am wrong at some place.

You are possibly setting a state directly inside the functional component when you are calling validate data and setMainDataSection.
So Firstly you need to define validateData before using it and secondly, you need to execute your check in a useEffect
const LiteraryPage = props => {
const validateData = async (data) => {
let finalDataArray = [];
if (data.cars !== undefined) {
finalDataArray = finalDataArray.concat(data.cars);
}
if (data.mobiles !== undefined) {
finalDataArray = finalDataArray.concat(data.mobiles);
}
if (data.scooters !== undefined) {
finalDataArray = finalDataArray.concat(data.scooters);
}
return finalDataArray;
};
useEffect(() => {
if (Object.keys(mainData).length === 0 && mainData.constructor === Object) {
setMainDataSection(validateData(mainData));
}
}, []);
}

Related

How to call API as promise in REACT

I am getting the following error when I run myu application and click on a submit button,
React has detected a change in the order of Hooks called by SideBarItemTemplateWithData. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks
Previous render Next render
------------------------------------------------------
1. useContext useContext
2. useMemo useState
My SideBarItemTemplateWithData,
RoomListRowProps): ReactElement {
const { sidebar } = useLayout();
let priority:any;
let userRoomId:any;
let data:any;
const href = roomCoordinator.getRouteLink(room.t, room) || '';
const title = roomCoordinator.getRoomName(room.t, room) || '';
if (room && room.v && room.v._id) {
userRoomId = room.v._id;
}
if (room && room.priorityId) {
data = useEndpoint('GET', `/v1/livechat/priorities/${room.priorityId}`);
}
if (data && data.value && data.value.name) {
priority = data.value.name.toLowerCase();
}
const {
lastMessage,
hideUnreadStatus,
hideMentionStatus,
unread = 0,
alert,
userMentions,
groupMentions,
tunread = [],
tunreadUser = [],
rid,
t: type,
cl,
} = room;
<SideBarItemTemplate
userId={userRoomId}
priority={priority}
is='a'
/>
I am getting the error when I run the above code but when I comment the following line it is working fine,
if (room && room.priorityId) {
data = useEndpoint('GET', `/v1/livechat/priorities/${room.priorityId}`);
}
The below line returns a promise,
useEndpoint('GET', `/v1/livechat/priorities/${room.priorityId}`);
Can anyone suggest me to how can I modify it o that the issue will be resolved. Thanks
useEndPoint code,
export const useEndpoint = <TMethod extends Method, TPath extends PathFor<TMethod>>(
method: TMethod,
path: TPath,
): EndpointFunction<TMethod, MatchPathPattern<TPath>> => {
const { callEndpoint } = useContext(ServerContext);
return useCallback((params: any) => callEndpoint(method,
path, params), [callEndpoint, path, method]);
};
How to use useEndPoint,
const sendEmailCode = useEndpoint('POST', '/v1/users.2fa.sendEmailCode');
await sendEmailCode({ emailOrUsername });
My Code,
const priorityData = useEndpoint('GET', `/v1/livechat/priorities/${room.priorityId}`);
if (room && room.v && room.v._id) {
userRoomId = room.v._id;
}
const onClickResendCode = async (): Promise<any> => {
try {
let priorityVal = '';
let data = await priorityData();
if (data && data.name) {
priorityVal = data.name.toLowerCase();
}
return priorityVal;
} catch (error) {
throw error;
}
};
priority = onClickResendCode();
Can anyone please suggest how can I modify the api call
The error is not about the promise, is about the order of the hook. In React you must keep the order of all your hook. You should not use your hook in a if or a loop.
This is the error.
if (room && room.priorityId) {
data = useEndpoint('GET', `/v1/livechat/priorities/${room.priorityId}`);
}
it should be
data = useEndpoint('GET', `/v1/livechat/priorities/${room.priorityId}`);
You can use if in the callEndpoint function, which is not a react hook.

React state updates when using object, but not when using array

I have a question about some weird behavior when using React state.
If I change the default type of the groupedFormErrors variable in the helper function to [] instead of {} the state in the page element formErrors doesn't update. Would be great if somebody could explain why this happens.
Page element
const [formErrors, setFormErrors] = useState();
const signUpHandler = async (e) => {
e.preventDefault();
const response = await submitForm();
if (response.status === 422) {
setFormErrors(groupFormErrors(response));
}
};
Helper function
export default function GroupFormErrors(response) {
let groupedFormErrors = {}; // <<<<<<<<<<<<<<<<<<<<< This here
if (response.status === 422) {
response.data.forEach((error) => {
if (groupedFormErrors.hasOwnProperty(error.param)) {
groupedFormErrors[error.param].push(error.msg);
} else {
groupedFormErrors[error.param] = [];
groupedFormErrors[error.param].push(error.msg);
}
});
}
return groupedFormErrors;
}

How do I pass index number to a react class?

Need help passing data "locationpos"= index of my Locations[] from function to class. I'm very new to React and I'm not sure what I'm doing wrong.
ERROR
Failed to compile
./src/components/data.js
Line 20:30: 'locationpos' is not defined no-undef
Search for the keywords to learn more about each error.
This error occurred during the build time and cannot be dismissed.
class Data {
constructor(locationpos) {
this.locationpos=locationpos;
this.updateData();
}
getTimes(date = null) {
date = date === null ? moment().format('DD/MM/YYYY') : date;
var data = this.getData();
return data ? data[date] : [];
}
getSpeadsheetUrl() {
return config.myData[locationpos];
}
function Daily({ locationProps = 1, root }) {
const context = useContext(ThemeContext);
const localization = useCallback(() => {
if (root && cookies.get("location") !== undefined) {
return cookies.get("location");
}
return locationProps;
}, [locationProps, root]);
const [locationState] = useState(localization());
const handleClick = event => {
window.focus();
notification.close(event.target.tag);
};
const openNav = () => {
document.getElementById("sidenav").style.width = "100%";
};
const closeNav = e => {
e.preventDefault();
document.getElementById("sidenav").style.width = "0";
};
// eslint-disable-next-line
const locationpos = locations.indexOf(locations[locationState]);
const _data = useRef(new Data(locationpos));
const getTimes = () => _data.current.getTimes();
Inside your data class, you need to use the instance variable as this.locationPos
getSpeadsheetUrl() {
return config.myData[this.locationpos];
}

How to fix the error "cannot read property then of undefined" react?

Hi i want to return the promise that gets resolved when the first poll finishes...
I have a start_polling method and i want to modify it such that it returns a promise that gets resolved when the items_promise gets resolved...i am not sure how to do it.
What i have tried?
i have created a promise in start_polling method that gets resolved when the item_promise_finish() is executed in then method of items_promise.
Once this promise in start_polling is resolved then i call handle_location method.
It works fine but sometimes i get error cannot read property then of undefined.
How can i fix it.
below is the code,
componentDidUpdate(prevProps, prevState) {
const {state, props} = this;
const current_id = props.item && props.item.id;
const prev_id = prevProps.item && prevProps.item.id;
if (current_id !== prev_id) {
this.stop_polling();
this.setState(this.get_initial_state(), () => {
this.start_polling();
});
} else {
const prev_poll = this.should_poll(prevProps, prevState);
const next_poll = this.should_poll(props, state);
if (prev_poll !== next_poll) {
if (next_poll) {
this.start_polling();
} else {
this.stop_polling();
}
}
if (this.props.location.search) {
this.start_polling().then(() => {
this.handle_location();
})
}
start_polling = () => {
if (this.should_poll(this.props, this.state)) {
this.poll();
return new Promise((resolve) => {
this.item_promise_finish=resolve;
});
}
};
poll = () => {
let still_polling = true;
if (this.cancel_poll_request) {
this.cancel_poll_request();
}
});
const items_promise = client.get_items(this.props.item.id,
cancel_poll_promise);
items_promise.then((request) => {
const next_items = [];
let something_changed = false;
for (const new_item of request.response) {
const old_item = this.state.items.find(
old_item =>
old_item.id === new_item.id);
if (old_item) {
next_items.push(old_item);
} else {
something_changed = true;
next_items.push(new_item);
}
}
if (something_changed) {
const next_state = {items: next_items};
this.setState(next_state);
}
}).then(() => {
if (still_polling) {
this.poll_timeout = setTimeout(this.poll, 100s);
}
this.item_promise_finish();
}).catch(this.props.notifications.request_error);
};
Could someone let me know where i am going wrong or what to be done to fix this. thanks.

how to unit test and get the value of localStorage on react

I'm testing out logout function on our react app and I'm having trouble testing the localStorage. What I want to do is check if (value === 'logout') in my unit test so I can have a expect assertion that will check if localStorage has the item i'm testing for, this is where I'm having trouble. How can I assert that if (value === 'logout') then equals localStorage.removeItem('id_token')
Here is the .js snippet I'm testing for
_handleSelectItem = (event, value) => {
if (value === 'logout') {
const sharedLogic = () => {
localStorage.removeItem('id_token')
window.location = '/' // TODO: find a better way to reset the relay cache
}
const onSuccess = (response) => {
sharedLogic()
}
const onFailure = (transaction) => {
var error = transaction.getError() || new Error('Mutation failed.')
console.error(error)
sharedLogic()
}
this.props.relay.commitUpdate(
new SignOutUserMutation({
viewer: this.props.viewer
}
), {onSuccess, onFailure})
}
}
Here is the .spec.js I wrote that didn't quite do the job that I wanted
if(!global.localStorage) {global.localStorage = {} }
// if(value === 'logout')
describe('(Component) AccountManager | Logout ', () => {
let _component
let _props
let value = 'logout'
// if(value === 'logout')
beforeEach(() => {
_props = {
viewer: {
email: 'joe#example.com'
}
}
_component = shallowRenderWithProps(_props)
sinon.spy(global.localStorage, 'getItem')
sinon.spy(global.localStorage, 'setItem')
sinon.spy(global.localStorage, 'clear')
})
afterEach(() => {
global.localStorage.getItem.restore()
global.localStorage.setItem.restore()
global.localStorage.clear.restore()
})
it('Should check if Logout work correctly', () => {
if(value === 'logout');
console.log(global.localStorage)
expect(global.localStorage.getItem.withArgs('id_token').calledOnce).is.true;
})
Note the test above passes but does not clear the CodeCov error that indicated I should test this. I'm just getting started with react so I appreciate the helping me learn more
if if (typeof(Storage) !== "undefined" && localStorage.getItem(value) === 'logout') {
//[do your stuff here]
}

Categories