Changing class component to functional component - javascript

Need to change this class component code into functional component, what are the required changes for converting this class component to functional component. Please check the code for the changes. I am more into using functional components, so I want this code to be converted to functional component
class MTS extends React.Component {
constructor(props) {
super(props);
this.state = {
message:null,
msgStatus: null,
version :null ,
data: [],
clusters:null
};
this.receiveData = this.receiveData.bind(this);
}
//************************************************************************
onGetAPI=()=>{
var _self = this;
fetch('http://127.0.0.1/api/v1/version')
.then(response =>
{
this.setState({ msgStatus : response.status, strStatusText : response.statusText }) // console.log(this.msgStatus) ;
return response.json();
})
.then(data => this.setState({ version : data }))
.then(function(json) {
console.log(json);
_self.receiveData(json);
});
}
//*************************************************************************
onGetClusters=()=>{
<label>Cluster ID <input style={{backgroundColor: "lightgray"}} type = "textarea" ref ="input"></input></label>
var _self = this;
fetch('http://127.0.0.1/api/v1/clusters')
.then(response =>
{
this.setState({ msgStatus : response.status , strStatusText : response.statusText}) // console.log(this.msgStatus) ;
return response.json();
})
//.then(data => this.setState({ clusters : data })
.then(function(json) {
console.log(json);
_self.receiveData(json);
} );
}
//*************************************************************************
receiveData(data) {
this.setState({data});
}
//*************************************************************************
onGetClustersID=()=>{
var _self1 = this;
let clusterinfo = this.refs.input.value;
//let clusterinfo1 =JSON.parse(clusterinfo);
console.log(clusterinfo);
fetch(' http://127.0.0.1/api/v1/clusters/'+ clusterinfo)
.then(response =>
{
this.setState({ msgStatus : response.status, strStatusText : response.statusText }) // console.log(this.msgStatus) ;
return response.json();
})
//.then(data => this.setState({ clusters : data })
.then(function(json) {
console.log(json);
_self1.receiveData(json);
} );
}
render(){
return(
<h4>Response status : {this.state.msgStatus} {this.state.strStatusText}</h4>
<h4> Output : {JSON.stringify(this.state.data)}</h4>
)
};
}

Here you are
// 1. create a function called MTS
import { useState } from 'react'
const MTS = () => {
// 2. using `useState`
const [state, setState] = useState({
message:null,
msgStatus: null,
version :null ,
data: [],
clusters:null
})
// 3. convert all method to lambda function
// remove var _self = this;
// replace this.setState => setState
// replace _self.receiveData => receiveData
const onGetAPI = ()=> {
fetch('http://127.0.0.1/api/v1/version')
.then(response =>
{
setState({ msgStatus : response.status, strStatusText : response.statusText }) // console.log(this.msgStatus) ;
return response.json();
})
.then(data => setState({ version : data }))
.then(function(json) {
console.log(json);
receiveData(json);
});
}
const receiveData = (data) => {
setState({data});
}
const onGetClusters = () => {
<label>Cluster ID <input style={{backgroundColor: "lightgray"}} type = "textarea" ref ="input"></input></label>
fetch('http://127.0.0.1/api/v1/clusters')
.then(response =>
{
setState({ msgStatus : response.status , strStatusText : response.statusText}) // console.log(this.msgStatus) ;
return response.json();
})
.then(function(json) {
console.log(json);
receiveData(json);
} );
}
const onGetClustersID = () => {
// let clusterinfo = this.refs.input.value;
// let clusterinfo1 =JSON.parse(clusterinfo);
console.log(clusterinfo);
fetch(' http://127.0.0.1/api/v1/clusters/'+ clusterinfo)
.then(response =>
{
setState({ msgStatus : response.status, strStatusText : response.statusText })
return response.json();
})
.then(function(json) {
console.log(json);
receiveData(json);
} );
}
return (
<h4>Response status : {state.msgStatus} {state.strStatusText}</h4>
<h4> Output : {JSON.stringify(state.data)}</h4>
)
}

Related

Quasar Q-table not updating with ref() array

When I update ref() array, q-table not updating.
I am initiating the rows ref with the "getApplications()" function.
Then when i call the reviewed() function from a line in the q-table, the table does not update with new data after i update the rows ref.
<q-table
v-model:selected="selected"
:loading="loading"
title="Applications"
:rows="rows"
:columns="columns"
row-key="id"
></q-table>
<script setup>
import { api } from "boot/axios";
import { ref } from "vue";
const columns = ref([ ........]);
let rows = ref([]);
getApplications();
function getApplications() {
api({
method: "get",
url: "/webdata/_partition/apply/_design/apply-list/_view/apply-list",
})
.then((response) => {
var row = fncArrayAll(response.data.rows);
rows.value = row;
})
.catch((e) => {
console.log("e: ", e);
alert(e);
})
.finally(() => {
loading.value = false;
});
}
function reviewed(prop) {
loading.value = true;
api({
method: "get",
url: "/webdata/" + prop.row._id,
})
.then((response) => {
var newData = response.data;
newData.office.reviewed = !newData.office.reviewed;
api({
method: "put",
url: "/webdata/" + prop.row._id,
data: newData,
})
.then((response) => {
console.log("new response: ", response);
})
.catch((e) => {
console.log("e: ", e);
alert(e);
})
.finally(() => {
loading.value = false;
});
})
.catch((e) => {
console.log("e: ", e);
alert(e);
})
.finally(() => {
loading.value = false;
});
}
function fncArrayAll(items) {
var filtered = [];
for (var i = 0; i < items.length; i++) {
filtered.push(items[i].value);
}
// console.log(filtered);
return filtered;
}
</script>
When rows is updated in the reviewed function, the q-table is not updated.
Thanks for any help

Passing data form parent to Child with the value fetch form API

I wanna passing the selectedCategory (it is State hook) to the Child Item,
First of all, I use the getServiceCatoriesAsync API (redux toolkit) and pass props.serviceCategories[0]?._id to State to fetch initialState (ID of Category).
In Child Component, I receive selectedCategory with the value: undefined
How to fix this.
const ServicesScreen = (props) => {
//! props: navigation, route,
//! props Redux: serviceCategories, getServiceCategoriesAsync
const nCount = React.useRef(0);
console.log(`ServicesScreen - render `, (nCount.current += 1));
const [selectedCategory, setSelectedCategory] = React.useState(props.serviceCategories[0]?._id);
React.useEffect(() => {
let isSubscribed = true;
if (isSubscribed) {
props.getServiceCategoriesAsync();
}
return () => {
isSubscribed = false; //! Cancel the subscription
};
}, [selectedCategory]);
return (
<View style={styles.container}>
<PanelServiceCategory
theme={theme}
style={styles.containerPanelCategory}
setSelectedCategory={setSelectedCategory}
selectedCategory={selectedCategory}
serviceCategories={props.serviceCategories}
{...props}
/>
<PanelServices style={styles.containerPanelService} />
</View>
);
};
servicesSlice
import { createAsyncThunk, createSlice } from '#reduxjs/toolkit';
import { PlatformBaseUrl } from '../../../utils';
//! GET ServiceCategory
export const getServiceCategoriesAsync = createAsyncThunk('services/getServiceCategoriesAsync', async () => {
const response = await fetch(PlatformBaseUrl.baseApiUrl('/api/services'));
if (response.ok) {
const { serviceCategories } = await response.json();
return serviceCategories; // payload Action
}
});
//! CREATE ServiceCategory
export const addServiceCategoryAsync = createAsyncThunk('services/addServiceCategoryAsync', async (payload) => {
const response = await fetch(PlatformBaseUrl.baseApiUrl('/api/services'), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: payload.name }),
});
if (response.ok) {
const { serviceCategory } = await response.json();
return serviceCategory; //! return Action 1 Array
}
});
//! CREATE Service
export const addServiceAsync = createAsyncThunk('services/addServiceAsync', async (payload, { getState }) => {
const { serviceCategoryId } = getState().modal.modalProps; //! OK
const response = await fetch(PlatformBaseUrl.baseApiUrl(`/api/services/${serviceCategoryId}`), {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name: payload.name, price: payload.price, description: payload.description }),
});
if (response.ok) {
const { service } = await response.json();
return service;
}
});
//! DELETE Service
export const removeServiceAsync = createAsyncThunk('services/removeServiceAsync', async (payload, { getState }) => {
const { serviceCategoryId, serviceId } = getState().modal.modalProps;
const response = await fetch(PlatformBaseUrl.baseApiUrl(`/api/services/${serviceCategoryId}/${serviceId}`), {
method: 'DELETE',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ serviceId }),
});
if (response.ok) {
const { service } = await response.json();
return service;
}
});
//! UPDATE Service
export const updateServiceAsync = createAsyncThunk('services/updateServiceAsync', async (payload, { getState }) => {
const { serviceCategoryId, serviceId } = getState().modal.modalProps;
const { name, price, description } = payload;
const response = await fetch(PlatformBaseUrl.baseApiUrl(`/api/services/${serviceCategoryId}/${serviceId}`), {
method: 'PATCH',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ name, price, description }),
});
if (response.ok) {
const { updatedService } = await response.json();
return updatedService; //! return a Object
}
});
const initialState = {
isLoading: false,
error: false,
serviceCategories: [],
};
const servicesSlice = createSlice({
name: 'services',
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(getServiceCategoriesAsync.pending, (state, action) => {
console.log('getServiceCategoriesAsync pending');
});
builder.addCase(getServiceCategoriesAsync.fulfilled, (state, action) => {
console.log('getServiceCategoriesAsync fulfilled');
state.serviceCategories = action.payload;
});
builder.addCase(addServiceCategoryAsync.fulfilled, (state, action) => {
console.log('addServiceCategoryAsync fulfilled');
state.serviceCategories.push(action.payload);
});
builder.addCase(addServiceAsync.pending, (state, action) => {
console.log('addServiceAsync pending');
});
builder.addCase(addServiceAsync.fulfilled, (state, action) => {
console.log('addServiceAsync fulfilled');
let categories = [...state.serviceCategories];
let catIndex = categories.findIndex((item) => item._id === action.payload.category);
if (catIndex != -1) categories[catIndex].services.push(action.payload);
state.serviceCategories = categories;
});
builder.addCase(removeServiceAsync.pending, (state, action) => {
console.log('removeServiceAsync pending');
});
builder.addCase(removeServiceAsync.fulfilled, (state, action) => {
console.log('removeServiceAsync fulfilled');
let categories = state.serviceCategories;
let catIndex = categories.findIndex((item) => item._id === action.payload.category);
let updatedServices = categories[catIndex].services.filter((service) => service._id !== action.payload._id);
if (catIndex != -1) state.serviceCategories[catIndex].services = updatedServices;
});
builder.addCase(updateServiceAsync.pending, (state, action) => {
console.log('updateServiceAsync pending');
});
builder.addCase(updateServiceAsync.fulfilled, (state, action) => {
console.log('updateServiceAsync fulfilled');
let categories = state.serviceCategories;
let catIndex = categories.findIndex((item) => item._id === action.payload.category);
let updatedServices = categories[catIndex].services.map((service) => (service._id === action.payload._id ? action.payload : service));
if (catIndex != -1) state.serviceCategories[catIndex].services = updatedServices;
});
},
});
//! exp Actions
export const {} = servicesSlice.actions;
//! exp Reducer
export default servicesSlice.reducer;
I wish I could comment this under your post but my rep is too low so oh well.
The problem may be caused due to several reasons. To debug you need to show the parent file which gives props.serviceCategories[0]?._id to ServicesScreen. And also show how it calls the redux store to gain access to said data.
Also show the slice that handles the state for serviceCategories. It might be the case that you are mutating the state and hence the store is not causing a re-render.
EDIT
Alright so basically you are mutating some states that Immer cannot handle in redux-toolkit.
the cases are wherever this has been done:
state.serviceCategories[catIndex].services = updatedServices;
According to the docs arrays are mutable in nature and changing them in such fashion means Immer cannot apply a copy to the state change (Although it is able to do so inside the createReducer() method). Therefore a better approach would be:
// inside updateServiceAsync.fulfilled and removeServiceAsync.fulfilled
let elementForInsertion = {...state.serviceCategories[catIndex], services: updatedServices}
if (catIndex != -1) state.seviceCategories = [...state.serviceCategories.slice(0,catIndex), elementForInsertion, ...state.serviceCategories.slice(catIndex+1)]

Get axios call in reactjs

Below is the response I am getting after doing get call:
{
    "id": “12345”,
    “details”: {
        “name”: “sample doc”,
        “market: “sample market”
    }
}
My Service Method:
ENDPOINTS = {
product: "/market/product",
}
getDetails(
id: string
): Promise<{
id: string;
}> {
const url = `${this.ENDPOINTS.PRODUCT}/${id}/name`;
return http
.get(url)
.then((response) => {
return response.data;
})
.catch((error) => {
throw error;
});
}
My component Method:
getTestingDone = () => {
this.sampleService
.getDetails(
this.props.product.id,
)
.then((response) => {
this.setState({
});
})
.catch((error) => {
console.log(error);
});
};
<TextInput
labelText="name"
type="text"
name="keyname"
value = {name}
/>
I want to print the response in this input field. Not sure How to get the response from the server to the UI. Can anyone help me with this.Do i need to make a model class? and return it in response in service method?
constructor() {
this.state = {
name: ''
}
}
getTestingDone = () => {
this.sampleService
.getDetails(this.props.product.id)
.then(({details: {name}}) => {
this.setState(state => ({...state, name}));
})
}
render() {
const { name } = this.state;
return <TextInput
labelText="name"
type="text"
name="keyname"
value = {name}/>
}
This is the correct answer for the above question:
constructor(){
this.state = {
details: {
name: "",
market: "",
}
}
getTestingDone = () => {
this.sampleService
.getDetails(this.props.product.id)
then((response) => {
this.setState({
credentials: response.credentials,
});
})
return <TextInput
labelText="name"
type="text"
name="keyname"
value = {this.state.details.name}/>
}
}

I am facing problem while sending fetch response object from one screen to another screen from switch navigator (react-navigation v3)

this is login screen action function from which i am navigating to another screen .
`
loginAction = () => {
const newState = !this.state.button_toggle;
this.setState({ button_toggle: newState });
const { userName } = this.state;
const { userPassword } = this.state;
const { schoolCode } = this.state;
const { loading } = this.state;
this.setState({ loading: true });
fetch('url',
{
method: 'post',
header: {
'Accept': 'application/json',
'Content-type': 'application/json'
},
body: JSON.stringify({
//passing param
userName: userName,
password: userPassword,
schoolCode: schoolCode
})
})
.then((response) => response.json())
.then((responseJson) => {
alert("response");
console.log(responseJson);
console.log("=======" + responseJson.studentInfo[0]);
console.log("N=" + responseJson.studentInfo[0].studentName);
console.log("test-" + responseJson.test[0].A);
console.log("test-" + responseJson.test[0].B);
console.log("test-" + responseJson.test[0].C);
const res = responseJson;
if (responseJson.Login == "Success" && responseJson.count == 21) {
this.setState({ button_toggle: false });
}
else if (responseJson.Login == "Success" && responseJson.count == 1) {
alert("Login Successful 1");
this.props.navigation.navigate('Dashboard', {
//myJSON: responseJson.studentInfo[0],
myJSON: responseJson,
Login: responseJson.Login,
studentName: responseJson.studentInfo[0].studentName,
studentId: responseJson.studentInfo[0].studentId,
studentRollNumber: responseJson.studentInfo[0].studentRollNumber,
studentImage: responseJson.studentInfo[0].studentImage,
classDescription: responseJson.studentInfo[0].classDescription,
studentSection: responseJson.studentInfo[0].studentSection,
})
} else {
alert("Login Failed ");
}
}).catch((error) => {
console.log(error);
alert(error);
})
}
getting the data in next screen like this
const Login = this.props.navigation.getParam("Login");
const K = this.props.navigation.getParam("K");
const studentName = this.props.navigation.getParam("studentName");
const studentId = this.props.navigation.getParam("studentId");
const studentRollNumber = this.props.navigation.getParam("studentRollNumber");
const classDescription = this.props.navigation.getParam("classDescription");
const studentSection = this.props.navigation.getParam("studentSection");
const classId = this.props.navigation.getParam("classId");
`
this is my navigation
const AppSwitchNavigator = createSwitchNavigator({
LoginScreen: { screen: LoginForm },
Dashboard: { screen: AppDrawerNavigator }
});
inside a stack navigator its working but in inside switch navigator its not working

Set default active tabs and tasks based on the returned values

If Get2 returnsnull, it tries to set the default to Get1 ->selectedTabId: res.data [0] .id, selectedTodoId: res.data [0] .id. If Get2 returns an object with the properties, it wants to set the active tab and the task based on what will returnGet2 `` selectedTabId: res.data.task_id, selectedTodoId: res.data.task_id. Currently, selectedTabId: res.data[0].id, selectedTodoId: res.data[0].id is always set for me. Get2 returns me a specific task (id) that appears in the array withGet1 Please, give me some tips.
Code here: https://stackblitz.com/edit/react-soyase
class App extends React.Component {
constructor() {
super();
this.state = {
selectedTodoId: '',
selectedTabId: null,
items: [],
selectIndex: null
};
}
componentDidMount() {
/*Get1*/
axios({
url: 'https://app',
method: "GET"
})
.then(res => {
this.setState({
items: res.data,
selectedTabId: res.data[0].id,
selectedTodoId: res.data[0].id
});
})
.catch(error => {
console.log(error);
})
/*Get2*/
axios({
url: 'https://app/tasks',
method: "GET"
})
.then(res => {
this.setState({
checkRunning: res.data,
checkRunningId: res.data.id,
selectedTabId: res.data.id
});
})
.catch(error => {
console.log(error);
})
}
select = (id) => {
this.setState({
selectedTodoId: id,
selectedTabId: id
})
}
isActive = (id) => {
return this.state.selectedTabId === id;
}
render() {
return (
<div>
<ul>
{
this.state.items
.map((item, index) =>
<Item
key={index}
index={index}
item={item}
select={this.select}
items = {this.state.items}
selectIndex = {this.state.selectIndex}
isActive= {this.isActive(item.id)}
/>
)
}
</ul>
</div>
);
}
}
You have to chain these promises directly, so that you can make sure, that the default Get1 is set, before you try to set the Get2. Look at this code to see how you could Implement it.
componentDidMount() {
/*Get1*/
axios({
url: 'https://app',
method: "GET"
})
.then(res => {
this.setState({
items: res.data,
selectedTabId: res.data[0].id,
selectedTodoId: res.data[0].id
});
})
.catch(error => {
console.log(error);
})
.then(() => {
/*Get2*/
axios({
url: 'https://app/tasks',
method: "GET"
})
.then(res => {
if (res) {
this.setState({
checkRunning: res.data,
checkRunningId: res.data.id,
selectedTabId: res.data.id
});
}
})
.catch(error => {
console.log(error);
})
});
}
Now you set the default id tab from Get1 and after that, you download Get2 and if Get2 returns a valid object (you could extend that if(res) to check if it is an actual object and a valid response), the downloaded Get2 id is set. Hope this helps.

Categories