Reload screen after action - REACT NATIVE - javascript

I want to have a screen which contains all my favorite subjects. I have to select these from another screen, with all the subjects. The functionallity behind it works fine, but the problem I'm having right now, is that when a subject is chosen as a favorite, it doesn't show up on the favorite screen... Only after a forced reload... Any ideas how I can fix this?
import {
Button,
Text,
View,
StyleSheet,
FlatList,
SafeAreaView,
StatusBar,
ScrollView,
} from "react-native";
import React, {Component, useContext, useState} from "react";
import Ionicons from 'react-native-vector-icons/Ionicons';
import {TouchableOpacity} from "react-native";
import getAccessToken from "../functions/getAccessToken";
import refreshToken from "../functions/refreshToken";
import Subject from "../functions/SubjectLoaders/Subject";
import styleSubjectList from "../styles/styleSubjectList";
import backendURL from "../backendURL";
import getFromStore from "../functions/getFromStore";
import {BottomTabBarHeightContext, useBottomTabBarHeight} from '#react-navigation/bottom-tabs';
import FavoriteSubject from "../functions/SubjectLoaders/FavoriteSubject";
import {AuthContext} from "../Authentication/AuthProvider";
function SubjectListScreen({navigation}) {
const [subjects, setSubjects] = useState([]);
const [details, setDetails] = useState([]);
const [hasLoaded, setHasloaded] = useState(false);
const tabBarHeight = useBottomTabBarHeight();
React.useEffect(()=> {
const constructor = async () => {
await refreshToken();
let token = await getAccessToken();
let ownId = await getFromStore("ownId")
console.log("ownId: " + ownId)
let axios = require('axios');
let config = {
method: 'get',
url: backendURL + '/subjectManagement/subjects',
headers: {
'Authorization': 'Bearer ' + JSON.parse(token)
}
};
axios(config)
.then(function (res) {
// console.log(res.data)
setSubjects(res.data);
setHasloaded(true);
//console.log(res.data);
}).catch(function (error) {
});
}
constructor();
},[])
// if(!hasLoaded) return null;
return(
<View style={styleSubjectList.container}>
<SafeAreaView style={{justifyContent: 'center',}}>
<FlatList
data={subjects}
renderItem={ ({item}) => {
return <FavoriteSubject subject={item}/>
}}
keyExtractor={ subject => subject.id }
/>
</SafeAreaView>
</View>
)
}
export default SubjectListScreen;
This is the page that should reload!
import React, {useContext, useState} from "react";
import { Pressable } from "react-native";
import { MaterialCommunityIcons } from "#expo/vector-icons";
import styleSubjectList from "../../../styles/styleSubjectList";
import refreshToken from "../../refreshToken";
import getAccessToken from "../../getAccessToken";
import getFromStore from "../../getFromStore";
import addToFavorites from "./addToFavorites";
import removeFromFavorites from "./removeFromFavorites";
import backendURL from "../../../backendURL";
import axios from "axios";
import removeFirstAndLast from "../../removeFirstAndLast";
import {AuthContext} from "../../../Authentication/AuthProvider";
import isRole from "../isRole";
const Hart = ({subject}) => {
const { userInfo } = useContext(AuthContext);
const [liked, setLiked] = useState(false);
const [hasloaded,setHasloaded] = useState(false);
const [ownId, setOwnId] = useState('');
const [token, setToken] = useState('');
const [favourite, setFavourite] = useState([]);
const favouriteId = [];
React.useEffect(()=> {
const constructor = async () => {
await refreshToken();
let token = await getAccessToken();
setToken(token);
let id = await getFromStore("ownId");
id = removeFirstAndLast(id)
setOwnId(id)
const axios = require('axios');
const config = {
method: 'get',
url: backendURL + '/userManagement/users/' + id,
headers: {
'Authorization': 'Bearer ' + JSON.parse(token)
}
};
axios(config)
.then(function (response) {
// setFavourite(response.data.favouriteSubjects)
for(let i = 0; i<response.data.favouriteSubjects.length; i++) {
if(response.data.favouriteSubjects[i].id === subject.id) setLiked(true)
}
})
}
constructor().then(() => {
setHasloaded(true);
}).catch(e=>console.log(e));
},[])
const checkFavorite = () => {
setLiked((isLiked) => !isLiked)
if(liked) {
console.log("verwijderen uit favorieten");
removeFromFavorites(subject,ownId, token);
}
else {
console.log("toevoegen aan favorieten");
addToFavorites(subject,ownId,token);
}
}
// console.log(favourite)
if(!hasloaded || isRole("ROLE_COORDINATOR",userInfo) || isRole("ROLE_PROMOTOR",userInfo) || isRole("ROLE_CONTACT",userInfo) || isRole("ROLE_ADMIN",userInfo)) return null;
else{
return (
<Pressable style={styleSubjectList.heartIcon} onPress={ () => checkFavorite()}>
<MaterialCommunityIcons
name={liked ? "heart" : "heart-outline"}
size={20}s
color={liked ? "red" : "white"}
/>
</Pressable>
);
}
};
export default Hart;
The function addToFavorites/removeFromFavorites should trigger the change...
import removeFirstAndLast from "../../removeFirstAndLast";
import backendURL from "../../../backendURL";
const removeFromFavorites = async (subject,ownId,token) => {
let axios = require('axios');
let qs = require('qs');
let data = qs.stringify({
'userId': ownId,
'subjectId': subject.id,
});
console.log(data)
let config = {
method: 'delete',
url: backendURL + '/userManagement/users/student/favouriteSubject',
headers: {
'Authorization': 'Bearer ' + JSON.parse(token),
'Content-Type': 'application/x-www-form-urlencoded'
},
data : data
};
axios(config)
// .then(function (response) {
// console.log(JSON.stringify(response.data));
// })
.catch(function (error) {
console.log(error);
});
}
export default removeFromFavorites;

use key={Date.now()} on the component your wanted to be changed.

Related

How to use getServerSideProps method

I'm trying to make my page SEO friendly by using getServerSideProps method. I have tried to google it but cannot find any specifc example for my case. I'm not sure how to do it. I have a useEffect method currently.
import Header from './Header.js';
import Footer from './Footer.js';
import React, { Component, useState, useEffect } from 'react';
import Link from 'next/link';
import { useParallax, ParallaxBanner } from "react-scroll-parallax";
import { useTranslation } from "react-i18next";
import axios from "axios";
//import { Link, useLocation } from 'react-router-dom';
import Post from "./Post";
function Article({postSlug}) {
const { t, i18n } = useTranslation();
const [post, setPost] = useState([]);
const [posts, setPosts] = useState([]);
const currentlocale = typeof window !== 'undefined' ? localStorage.getItem('locale') : null;
useEffect(() => {
if(postSlug){
axios({
method: "POST",
url: process.env.NEXT_PUBLIC_API_URL + '/pages/article',
headers: { 'Content-Type': 'application/json;charset=UTF-8', "Access-Control-Allow-Origin": "*", "Accept": "application/json" },
data: {
country: currentlocale,
slug: postSlug
}
}).then(result => {
setPost(result.data.json.article);
setPosts(result.data.json.articles);
});
}
}, [postSlug])
return (
<div id="web-front">
<Header />
{post.title}
<Footer />
</div>
)
}
export default Article;
getServerSideProps only runs on routes / files created inside /pages folder.
Move your data fetching methods from the component to the getServerSideProps function.
You can get postSlug from the context.req[1] object getServerSideProps receives.
LocalStorage won't be available on server. Instead use cookies as a replacement for localStorage, since cookies is available on the context.req object. [2]
function Article({ initialPost, initialPosts }) { //👈 received from ssr props
const { t, i18n } = useTranslation();
const [post, setPost] = useState(initialPost); // set initially
const [posts, setPosts] = useState(initialPosts); // set initially
return (
<div id="web-front">
<Header />
{post.title}
<Footer />
</div>
);
}
export async function getServerSideProps(ctx) {
const postSlug = ctx.req.params.postSlug; // 👈 handled by you
const currentLocale = getCurrentLocaleFromCookies(ctx.req); // 👈 handled by you
let initialData = {};
try {
initialData = await axios({
method: 'POST',
url: process.env.NEXT_PUBLIC_API_URL + '/pages/article',
headers: {
'Content-Type': 'application/json;charset=UTF-8',
'Access-Control-Allow-Origin': '*',
Accept: 'application/json',
},
data: {
country: currentlocale,
slug: postSlug,
},
});
} catch (err) {
console.error(err);
}
return {
props: {
initialPost: initialData.data.json.article,
initialPosts: initialData.data.json.articles,
},
};
}
export default Article;
Reference:
https://nextjs.org/docs/api-reference/data-fetching/get-server-side-props
https://stackoverflow.com/a/63875689/7679903

How to deal with {AxiosError: Request failed with status code 401} axios/react/typescript ?Bearer token

Problem is that i have bearer token for API but for some reason my identification doesn't work{bearer token :wm3gg940gy0xek1ld98uaizhz83c6rh2sir9f9fu} Thanks in advance for your help
import React, { FC, useState, useEffect } from "react";
import axios from "axios";
import { IUser } from "../types/Types";
import List from "./List";
import UserItem from "./UserItem";
const HomePage: FC = () => {
const [users, setUsers] = useState<IUser[]>([]);
useEffect(() => {
fetchUsers();
}, []);
async function fetchUsers() {
try {
const response = await axios.get<IUser[]>(
"https://api.json-generator.com/templates/ZM1r0eic3XEy/data",
{
method: "post",
headers:new Headers({ Authorization:'Bearer
'wm3gg940gy0xek1ld98uaizhz83c6rh2sir9f9fu
'})
}
);
setUsers(response.data);
} catch (e) {
alert(e);
}
}
return (
<List
items={users}
renderItem={(user) => <UserItem user={user} key={user.id} />}
/>
);
};
export default HomePage;

why am I getting an error in fetching data here?

I have this for saving fetched data in state:
import React, {useState, useEffect, createContext} from 'react';
import { getLocation } from '../api';
export const LocationContext = createContext();
const LocatonContextProvider = (props) => {
const [location, setLocation] = useState({})
useEffect(() => {
const fetchAPI = async () => {
setLocation(await getLocation());
}
fetchAPI();
}, [])
return (
<LocationContext.Provider value={location}>
{props.children}
</LocationContext.Provider>
);
};
export default LocatonContextProvider;
and this for saving weather data
import React, {useState, useEffect, createContext, useContext} from
'react';
//api
import { getWeather } from '../services/api';
//Context
import { LocationContext } from '../contexts/LocationContextProvider';
export const WeatherContext = createContext()
const WeatherContextProvider = ({children}) => {
const location = useContext(LocationContext);
const lat = location.lat;
const lon = location.lon;
const [weather, setWeather] = useState({});
useEffect(() => {
const fetchAPI = async () => {
setWeather(await getWeather(lat,lon));
}
fetchAPI();
}, [lat, lon])
return (
<WeatherContext.Provider value={weather}>
{children}
</WeatherContext.Provider>
);
};
export default WeatherContextProvider;
and here is the axios request:
import axios from "axios";
const getLocation = async () => {
const LOCATION_URL = 'http://ip-api.com/json/?fields=country,city,lat,lon,timezone';
const response = await axios.get(LOCATION_URL);
return response.data;
}
const getWeather = async (lat, lon) => {
const WEATHER_URL = `https://api.openweathermap.org/data/2.5/weather?
lat=${lat}&lon=${lon}&appid=bac9f71264248603c36f011a991ec5f6`;
const response = await axios.get(WEATHER_URL)
return response.data;
}
export {getLocation, getWeather};
When I refresh the page, I get an 400 error and after that I get the data, I don't know why the error occurs
useEffect(() => {
const fetchAPI = async () => {
setWeather(await getWeather(lat,lon));
}
if (lat && lon) {
fetchAPI();
}
}, [lat, lon])

Why does it make a mistake?

The code below is not working. It doesn't see the apikey in parentheses.I couldn't understand what I had to do here. Is it a problem with the hooks structure?
import React, { useEffect } from 'react';
import MovieListing from "../MovieListing/MovieListing";
import movieApi from "../../common/apis/movieApi";
import { APIKey } from "../../common/apis/MovieApiKey"; //the program does not see this
import "./Home.scss";
import { useDispatch } from 'react-redux';
import { addMovies } from '../../features/movies/movieSlice';
const Home = () => {
const dispatch = useDispatch();
useEffect(() => {
const movieText = "Harry";
const fetchMovies = async () => {
const response = await movieApi.get('?apiKey=${APIKey}&s=${movieText}&type=movie')
.catch((err) => { console.log("Err :", err) });
dispatch(addMovies)(response.data); //api key does not see this
};
fetchMovies();
}, []);
return (
<div>
<div className='banner-img'></div>
<MovieListing />
</div>
);
};
export default Home;

TypeError: X is not a function / X is defined but never used

I'm getting the not a function error on addExperience() despite the fact that the function I'm using is defined as such. It's modeled off of other functions that work just fine. At the same time, I'm also getting the "defined but never used" warning.
addExperience.js:
import React, {Fragment, useState} from "react";
import {Link, withRouter} from "react-router-dom";
import PropTypes from "prop-types";
import {connect} from "react-redux";
import {addExperience} from "../../actions/profile";
...
const onSubmit = (e) => {
e.preventDefault();
addExperience(formData, history);
};
...
actions/profile.js:
import axios from "axios";
import {setAlert} from "./alert";
import {GET_PROFILE, PROFILE_ERROR, UPDATE_PROFILE} from "./types";
...
export const addExperience = (formData, history) => async (dispatch) => {
try {
const config = {
headers: {
"Content-Type": "application/json",
},
};
const res = await axios.post("/api/profile/experience", formData, config);
dispatch({
type: UPDATE_PROFILE,
payload: res.data,
});
dispatch(setAlert("Experience Added", "success"));
history.push("/dashboard");
} catch (err) {
const errors = err.response.data.errors;
if (errors) {
errors.forEach((error) => dispatch(setAlert(error.msg, "danger")));
}
dispatch({
type: PROFILE_ERROR,
payload: {msg: err.response.statusText, status: err.response.status},
});
}
};

Categories