What would be the equivalent code in reactjs for this angularjs code - javascript

I'm working on a website which was based on angularjs. Now I want to convert few snippets into reactjs and I never used angular so obviously I'm having problem understanding few of the codes written in angularjs. I understand some of the code written here as it is used to save a post and show error when it's not saved. but i don't understand $scope and how to convert this piece of code to react. I hope someone could help me
$scope.savepost=function(){
$scope.postdata={}
$scope.postdata['postTitle']=$scope.postTitle
$scope.postdata['postDescription']=$scope.postDescription
console.log($scope.postId)
if($scope.postId==null){
return $http.post('/api/saveposts',$scope.postdata).then(function(response){
if(response.status==200){
$scope.postId=response.data;
toaster.pop('success','post saved successfully!')
}else{
toaster.pop('danger','An error has occured while saving the post. Please try again')
}
});
}else{
$scope.postdata['postId']=$scope.postId
return $http.post('/api/updateposts',$scope.postdata).then(function(response,status){
if(response.status==200){
toaster.pop('success','post saved successfully!')
}else{
toaster.pop('danger','An error has occured while updating the post. Please try again')
}
});
}
}

It would look something like this:
// destructure postId from props
const SomeFormComponent = ({ postId }) => {
const [postState, setPostState] = useState({title: '', description: ''})
/*
This example assumes you've set your input values to postState
*/
const handleRequest= async (url) => {
// copy all the input values set to state
const post = {...postState}
// this will be passed into fetch
const request = {
method: 'POST'
headers: {
'Content-Type': 'application/json'
}
}
if(postId != null) post['id'] = postId
try {
// use fetch, stringify json
const response = await fetch(url, { ...request, body: JSON.stringify(post )})
// handle json response
const data = await response.json()
if (data.status == 200) {
toaster.pop('success', 'post saved successfully!')
/*
Do something with the response
*/
} else {
toaster.pop('danger', 'An error has occurred while updating the post. Please try again')
}
} catch(ex) => {
console.error(ex.stack)
toaster.pop('danger', 'An error has occurred while updating the post. Please try again')
}
}
const handlePost = () => {
if(postId == null) {
return handleRequest('/api/savepost')
}
return handleRequest('/api/updatepost')
}
return (<button onClick={handlePost}>Save</button>)
}

Related

Variable "$id" got invalid value "1"; Int cannot represent non-integer value: "1"

I've been learning the mern stack from this book
I'm now on Nested Routes under React Router chapter
The web application is supposed to render this on the page.
When clicking the Select link under the Action column, the description of
an issue is displayed on the bottom part of the page.
But in my case, this thing happens:
and at the same time this error is being thrown in the console:
The only time the web application runs properly is when I downgraded the
graphql version to 0.13.2 (this is the version the book uses).
The thing is I try to use up to date versions of the project dependencies
as much as possible. There has never been much trouble as I follow the book
until I got into this.
I don't understand, why is this error being thrown when I use a more up to
date version of the graphql over the old version?
(I use graphql version 15.8.0 and apollo-server-express version 2.25.4)
I tried to modify the .jsx file that renders the description data
on the page.
async loadData() {
const { match: { params: { id } } } = this.props;
//I tried to parse the id to make it an int type before getting it into
//the graphql query
id = parseInt(id); // this is the thing that I've added
const query = `query issue($id: Int!) {
issue (id: $id) {
id description
}
}`;
const data = await graphQLFetch(query, { id });
if (data) {
this.setState({ issue: data.issue });
} else {
this.setState({ issue: {} });
}
}
This is the codes graphQLFetch function
const dateRegex = new RegExp('^\\d\\d\\d\\d-\\d\\d-\\d\\d');
function jsonDateReviver(key, value) {
if (dateRegex.test(value)) return new Date(value);
return value;
}
async function graphQLFetch(query, variables = {}) {
try {
const response = await fetch(window.ENV.UI_API_ENDPOINT, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ query, variables }),
});
const body = await response.text();
const result = JSON.parse(body, jsonDateReviver);
if (result.errors) {
const error = result.errors[0];
if (error.extensions.code === 'BAD_USER_INPUT') {
const details = error.extensions.exception.errors.join('\n');
alert(`${error.message}:\n ${details}`);
} else {
alert(`${error.extensions.code}: ${error.message}`);
}
}
return result.data;
} catch (e) {
alert(`Error in sending data to server: ${e.message}`);
return null;
}
}
When I did this, it doesn't throw any error anymore but it doesn't render
the description data on the page either.
Can someone please help me with this?? Thanks in advance...

Vue JS/Vuex - Call to edit user not saving

I'm trying to make an api call that allows me to edit a single user. The issue that I'm experiencing is that despite the call being successful (and no errors appearing), the changes are not saving. Can someone kindly guide me as to what I'm doing wrong exactly, please? I feel that I'm missing a function that allows me to save the changes after I make the call, but I'm not entirely sure how to go about this.
Edit user details:
setup() {
const store = vuexStore;
const adminId = router.currentRoute.params.adminId;
/** Edit **/
function editUser(formData) {
formData.adminId = adminId;
editAdminAccount(formData).then(response => {
if (response) {
redirectUserTo(ROUTE_NAMES_ADMIN.ADMIN_ACCOUNTS);
saveUserChanges(formData);
}
})
}
// Action
function editAdminAccount(data) {
return store.dispatch(UPDATE_ADMIN_ACCOUNT, data);
}
getSelectedAdmin(adminId);
const selectedAdmin = computed(() => store.getters.getSelectedAdmin);
function getSelectedAdmin(adminId) {
return store.dispatch(GET_ADMIN_BY_ID, adminId)
}
return {
editUser,
selectedAdmin,
}
}
Actions:
updateAdminAccount({commit}, payload) {
let formData = new FormData()
formData.append('email', payload.email)
formData.append('name', payload.name)
formData.append('password', payload.password);
return apiHandler.put(`user/admin/${payload.adminId}`, formData, apiHandler.getAuthHeader()).then(response => {
return !!apiHandler.isSuccess(response.status);
}).catch(error => {
commit(SET_API_ERROR, error);
});
},
You should maybe check what the api call is returning with some console.logs to be sure of the data that is sent back.
Nevertheless, do not have to work with formdata, you can send your query items directly :
updateAdminAccount({commit}, payload) {
return apiHandler.put(`user/admin/${payload.adminId}`, payload, apiHandler.getAuthHeader())
.then(response => !!apiHandler.isSuccess(response.status))
.catch(error => commit(SET_API_ERROR, error));
}
You also should edit the user directly after the api call in the action, and not from the template. So that the logic is kept at one place :
updateAdminAccount({commit}, payload) {
return apiHandler.put(`user/admin/${payload.adminId}`, payload, apiHandler.getAuthHeader())
.then(response => {
if (!!apiHandler.isSuccess(response.status)) {
commit('UPDATE_ADMIN', payload) // payload or response.data depending if api is returning edited object
}
return !!apiHandler.isSuccess(response.status)
})
.catch(error => commit(SET_API_ERROR, error));
}

How to use UseEffect every time get user and axios?

I use MERN stack and redux. I have two problem and please help me.
1) Every component react I add this:
const user = useSelector( state => state.user );
useEffect( ()=>{
dispatch(User_Auth(12)) ; // I write 12 for action work.
});
I want to get user data every time if user loginned or not. Is it true? or some idea have?
2) In backend if data current I send using 200 status codes. another variant I send data other status like this:
router.get('/auth', (req, res) => {
if(req.isAuthenticated()){
req.user.isAuth = true;
res.status(200).json(req.user);
}
else{
return res.status(401).json({
isAuth: false
});
}
});
This is my action get User data:
export const User_Auth = (value) => async (dispatch) => {
value = value + 0;
await axios({
method: "GET",
url:'http://localhost:3001/api/users/auth',
withCredentials:true
})
.then(res => {
dispatch({type: user_auth, payload: res.data});
}).catch(error => {
// console.log("Auth geldim: ", error);
});
}
I want if cannot see errors in console.log browser. Can I do that?
Thanks
If you want to see the status code from an error you have to access it like this
error.status
And to get the message
error.message

Can React app handle error (status code 4xx) with try catch block

I'm learning React (with hooks) and I encountered a weird issue. Im currently working on Notes Application (from FullStackOpen learn react). My database only accepts notes which content length is greater than 4 characters. In case of invalid note my server catches a ValidationError and returns an error message with status code 401 instead of new note. My goal is to catch this error in frontend and display an error message.
Backend code:
try{
const savedNote = await note.save()
user.notes = user.notes.concat(savedNote._id)
await user.save()
response.json(savedNote.toJSON())
} catch(e) {
//console.log(e.name)
const msg = {error: 'too short!!!'}
//console.log(msg)
return response.status(401).json(msg)
}
Problem appears when I try to receive data at the front side of application. My development console displays Error: Request failed with status code 401 no matter what I do. I can't find a way to enter catch block at front.
Frontend code for communication with server:
const create = async newObject => {
const config = { headers: { Authorization: token } }
const response = await axios.post(baseUrl, newObject, config)
console.log(response.data)
return response.data
}
(...)
const addNote = (event) => {
event.preventDefault()
try{
const noteObject = {
content: newNote,
date: new Date().toISOString(),
important: Math.random() > 0.5
}
noteService
.create(noteObject)
.then(returnedNote => {
setNotes(notes.concat(returnedNote))
setNewNote('')
setErrorMsg('')
setUserNotes(userNotes.concat(returnedNote))
})
} catch (e) {///<----how to get there
setErrorMsg('note too short! minimum 5 characters')
setNewNote('')
setTimeout(() => {
setErrorMsg(null)
}, 5000)
}
}
Some advices would be appreciated.
Solution:
Chaining promises - .catch()
const addNote = (event) => {
event.preventDefault()
const noteObject = {
content: newNote,
date: new Date().toISOString(),
important: Math.random() > 0.5
}
noteService
.create(noteObject)
.then(returnedNote => {
setNotes(notes.concat(returnedNote))
setNewNote('')
setErrorMsg('')
setUserNotes(userNotes.concat(returnedNote))
})
.catch(e => {
setErrorMsg('note too short! minimum 5 characters')
setNewNote('')
setTimeout(() => {
setErrorMsg(null)
}, 5000)
})
}
Put the try, catch block around your api call:
try {
const response = await axios.post(baseUrl, newObject, config)
} catch (e) {
// handle error
}
On another note, I don't recommend using 401 as the invalid status code as that has a reserved meaning of Unauthorized. Use 400 (Bad request) instead. The definitions of status codes: https://httpstatuses.com/

Angular - LocalStorage empty on start, fills on refresh (F5)

I create a simple login form on Angular (v8). On return response, I save it in localStorage like this
this.loginCtrl.login(form.value).subscribe(
response => {
console.log(response["token"]); //IS CORRECT
if (response["token"] != null) {
localStorage.setItem("token", response["token"]);
}
})
Then I want to get the token and send it to other services.
const httpOptions = {
headers: new HttpHeaders({
Authorization: "Token " + localStorage.getItem("token")
})
};
getGroupsByEntityAndUser(id: string, user: String) {
return this.http.get(
"URL" +
id +
"/username/" +
user,
httpOptions
);
}
The problem appears when I load the home page. The console returns that the token is null so the response is null. When I refresh the page with F5 I get the token and getGroupsByEntityAndUser function works properly. It´s a bit strange.
So the question is: Why when I load the first time localStorage is null but when I refresh the page is filled? It is necessary to be filled without refresh.
this.loginCtrl.login(form.value).subscribe(
async (response) => {
await this.handleToken(response);
// Execute your Next Code
});
handleToken(data) {
if (!localStorage.getItem('token')) {
localStorage.setItem('token', data.token);
}
}
The localStorage.getItem-method is asynchronous, please use fat arrow function to catch the result when available, like here:
try {
this.storage.get('eqs').then( eqlist => {
let _entries = JSON.parse(eqlist);
_entries.forEach( el => {
this.savedEQs.push(el);
});
});
} catch (e) {
console.log('no entries found!');
}
}

Categories