I want to ask for your help.
Earlier I got a Reactjs search filter tutorial on a web which I forgot where the source came from.
the code is like this =>
import React, { useEffect, useState } from "react";
import axios from "axios";
const Users = () => {
const [users, setUsers] = useState([]);
const [mainUsers, setMainUsers] = useState([]);
useEffect(() => {
axios
.get("https://jsonplaceholder.typicode.com/users")
.then((res) => {
setUsers(res.data);
setMainUsers(res.data);
})
.catch((err) => {
console.log(err);
});
}, []);
const handleSearch = (e) => {
setUsers(
mainUsers.filter((u) =>
u.name.toLowerCase().includes(e.target.value.toLowerCase())
)
);
console.log(e.target.value);
};
return (
<div className={`mt-5 p-4 container-fluid`}>
<div className="row my-2 mb-4 justify-content-between w-100 mx-0">
<div className="form-group col-10 col-md-6 col-lg-4">
<input
type="text"
className="form-control shadow"
placeholder="Search"
onChange={handleSearch}
/>
</div>
</div>
{users.length ? (
<table className="table">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Name</th>
<th scope="col">User Name</th>
<th scope="col">Email</th>
<th scope="col">Action</th>
</tr>
</thead>
<tbody>
{users.map((u) => (
<tr key={u.id}>
<th scope="row">{u.id}</th>
<td>{u.name}</td>
<td>{u.username}</td>
<td>{u.email}</td>
<td>
<i className="fa fa-edit text-warning"></i>
<i className="fa fa-edit text-warning pointer"></i>
</td>
</tr>
))}
</tbody>
</table>
) : (
<h6 className="text-center text-info">wating ...</h6>
)}
</div>
);
};
export default Users;
then I have an endpoint that has params, like this =>
xxxx.com/api/dashboard/v1/getCountPoiCategoryProvinsi?provinsi=jakarta
The question is,
how to change the initial url (https://jsonplaceholder.typicode.com/users") to this url (xxxx.com/api/dashboard/v1/getCountPoiCategoryProvinsi?provinsi=jakarta) ?
I don't know how to change it Thank you, I really appreciate your help.
Related
I am beginner of react. I want to add and edit both operations at one button.
but it is not working. what i tried so far is the attached code along with the screenshot image.
I will able to add the records and able to view the records when i click the table row particular row record will be passing to form successfully. But I want edit and add the record of same button. i create the method save inside method I called save and edit functions
screenshot
this is the function i wrote the below
async function save(users)
import axios from 'axios';
import {useEffect, useState } from "react";
function EmployeeLoad()
{
const [name, setName] = useState("");
const [address, setAddress] = useState("");
const [mobile, setMobile] = useState("");
var currentEmployeeID = "";
const [users, setUsers] = useState([]);
useEffect(()=>
{
Load();
},[])
async function editEmployee(users)
{
setName(users.name);
setAddress(users.address);
setMobile(users.mobile);
currentEmployeeID = users.id;
console.log(users.id);
}
async function Load()
{
const result = await axios.get(
"http://127.0.0.1:8000/api/employees");
setUsers(result.data);
console.log(result.data);
}
async function save(users)
{
if(users.id == '')
{
await axios.post("http://127.0.0.1:8000/api/save",
{
name: name,
address: address,
mobile: mobile
}
);
alert("Employee Registation success");
}
else
{
alert("edit");
}
}
return (
<div>
<h1>Employee Details</h1>
<div class="container mt-4" >
<form>
<div class="form-group">
<label>employeeName</label>
<input type="text" class="form-control" id="employeeName"
value={name}
onChange={(event) =>
{
setName(event.target.value);
}}
/>
</div>
<div class="form-group">
<label>employeeAddress</label>
<input type="text" class="form-control" id="employeeAddress"
value={address}
onChange={(event) =>
{
setAddress(event.target.value);
}}
/>
</div>
<div class="form-group">
<label>Mobile</label>
<input type="text" class="form-control" id="employeeMobile"
value={mobile}
onChange={(event) =>
{
setMobile(event.target.value);
}}
/>
</div>
<button class="btn btn-primary mt-4" onClick={save}>Register</button>
</form>
</div>
<table class="table table-dark" align="center">
<thead>
<tr>
<th scope="col">Employee Id</th>
<th scope="col">Employee Name</th>
<th scope="col">Employee Address</th>
<th scope="col">Employee Mobile</th>
<th scope="col">Option</th>
</tr>
</thead>
{users.map(function fn(item)
{
return(
<tbody>
<tr>
<th scope="row">{item.id} </th>
<td>{item.name}</td>
<td>{item.address}</td>
<td>{item.mobile}</td>
<td>
<button type="button" class="btn btn-warning" onClick={() => editEmployee(item)} >Edit</button>
<button type="button" class="btn btn-dark" >Delete </button>
</td>
</tr>
</tbody>
);
})}
</table>
</div>
);
}
export default EmployeeLoad;
Inside your table use the currentEmployeeID and render a save button if you are in edit mode
{currentEmployeeID === item.id ? (
<button type="button" class="btn btn-warning" onClick={save} >Save</button> : (
<button type="button" class="btn btn-warning" onClick={() => editEmployee(item)} >Edit</button>
)}
So if this specific row is in edit mode, by pressing the button, it will save the entry, or else it will show "Edit". Dont forget to reset the currentEmployeeID when the save process completes.
I have a dynamic Accordion in ReactJs. I am getting the message from my backend. but it's printing in every Accordion. I'm sharing the code
import React, { useState, useEffect } from "react";
import ApplicantDash from "./ApplicantDash";
import {
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
} from "#material-ui/core";
import * as FcIcons from "react-icons/fc";
import ApplicantService from "../services/ApplicantService";
export default function AvailJobs() {
const [aplcntEmail, setAplcntEmail] = useState("aman#gmail.com"); //change to aplcntemail
const [isShow, setIsShow] = useState(false);
const [msg, setMsg] = useState([""]);
const [job, setJob] = useState([
{
jobTitle: "",
dateOfPosting: Date,
lastDateToApply: new Date().toLocaleDateString([], {
year: "numeric",
month: "long",
day: "numeric",
}),
preferableSkills: [],
requiredExp: 0,
recruiterEmail: "",
companyName: "",
companyAddress: "",
},
]);
useEffect(() => {
const data = ApplicantService.getAllJobs()
.then((response) => {
console.log(response.data);
setJob(response.data);
})
.catch((error) => {
alert(error.response.data);
});
}, []);
const onApplyButton = (item,key) => {
const data2 = ApplicantService.applyForJob(aplcntEmail, item)
.then((response) => {
console.log(response.data);
setIsShow(true);
setMsg(response.data)
})
.catch((error) => {
setIsShow(true);
setMsg(error.response.data);
});
};
return (
<div>
<ApplicantDash />
<div className="container bg-light">
<div className="card-bodies">
<section className="mb-4">
<h2 className="h1-responsive font-weight-bold text-center my-4">
All Available jobs
</h2>
</section>
{job.map((item, key) => (
<>
<Accordion key={key}>
<AccordionSummary
expandIcon={<FcIcons.FcExpand />}
aria-controls="panel1a-content"
id="panel1a-header"
className="Accordian"
>
<Typography>
<div className="d-flex p-1 justify-content-evenly">
<div className="p-1">
<b> Job: </b> {item.jobTitle}
</div>
<div className="p-2"></div>
<div className="p-1">
<b> Company: </b> {item.companyName}
</div>
<div className="p-2"></div>
<div className="p-1">
<b> Last Date: </b> {item.lastDateToApply}
</div>
</div>
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
<div className="container">
<table class="table table-borderless">
<tbody>
<tr>
<td>JOB TITLE</td>
<td>:</td>
<td>
<b>{item.jobTitle}</b>
</td>
</tr>
<tr>
<td>Company</td>
<td>:</td>
<td>
<b>{item.companyName}</b>
</td>
</tr>
<tr>
<td>Address</td>
<td>:</td>
<td>
<b>{item.companyAddress}</b>
</td>
</tr>
<tr>
<td>Last Date to Apply</td>
<td>:</td>
<td>
<b>{item.lastDateToApply}</b>
</td>
</tr>
<tr>
<td>Experience</td>
<td>:</td>
<td>
<b>{item.requiredExp}</b>
</td>
</tr>
<tr>
<td> Skills </td>
<td>:</td>
<td>
<table className="table table-condensed w-auto table-borderless table-hover">
{item.preferableSkills.map((S, index1) => {
return (
<tbody key={index1}>
<td scope="col">
{index1 + 1}.<b>{S}</b>
</td>
</tbody>
);
})}
</table>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<button
type="button"
class="btn btn-primary"
onClick={() => onApplyButton(item,key)}
>
Apply for the job{" "}
</button>
</td>
</tr>
</tbody>
{isShow && <>
{msg}
</>}
</table>
</div>
</Typography>
</AccordionDetails>
</Accordion>
</>
))}
</div>
</div>
</div>
);
}
Now when I click on Apply for this job button. The message I get from backend prints only to Active accordion
Here some pictures which might help.
enter image description here
As you can see the response from backend is prints in the both of the accordion
Issue
The issue here is that you've a single boolean isShow state and a single msg state, and all the accordion detail sections use the same single isShow state to conditionally render the msg state.
Solution
A simple solution would be to store the id, or title, or index, of the accordion to show the message of.
Example:
export default function AvailJobs() {
...
const [isShow, setIsShow] = useState({}); // <-- initially empty object
...
const onApplyButton = (item, key) => {
ApplicantService.applyForJob(aplcntEmail, item)
.then((response) => {
console.log(response.data);
setMsg(response.data);
})
.catch((error) => {
setMsg(error.response.data);
})
.finally(() => {
setIsShow(show => ({
...show,
[key]: true // <-- set true the specific key
}));
});
};
return (
<div>
...
{job.map((item, key) => (
<Accordion key={key}>
...
<AccordionDetails>
<Typography>
<div className="container">
<table class="table table-borderless">
<tbody>
...
<tr>
...
<td>
<button
type="button"
class="btn btn-primary"
onClick={() => onApplyButton(item, key)}
>
Apply for the job
</button>
</td>
</tr>
</tbody>
{isShow[key] && <>{msg}</>} // <-- check if isShow[key] is truthy
</table>
</div>
</Typography>
</AccordionDetails>
</Accordion>
))}
...
</div>
);
}
I made a dynamic input table component with react-hook-form. You are able to add, remove and edit fields in the table. Here's how it looks like
import {useFieldArray, useFormContext} from "react-hook-form";
import {cloneElement} from "react";
import {IoMdAdd, IoMdRemoveCircle} from "react-icons/io";
interface TableData {
tableName:string,
inputFields: {
title: string,
name: string,
inputComponent: any,
}[],
inputBlueprint: object,
min?: number
};
const InputTable = ({tableName, inputFields, inputBlueprint, min}: TableData) => {
const {fields, remove, append} = useFieldArray({name: tableName});
const {register, formState: {errors}} = useFormContext();
return (
<table className="table-auto border-collapse block m-auto w-fit max-w-xs max-h-48 overflow-auto sm:max-w-none my-3">
<thead className="text-center">
<tr>
{inputFields.map((input) => (
<td className="border-2 border-gray-400 px-5" key={input.title}>{input.title}</td>
))}
</tr>
</thead>
<tbody>
{fields.map((field, index) => (
<tr key={field.id}>
{inputFields.map((input) => (
<td key={input.title} className="border-gray-400 border-2 p-0">
{cloneElement(input.inputComponent, {
className: "bg-transparent outline-none block w-full focus:bg-gray-400 dark:focus:bg-gray-500 p-1",
...register(`${tableName}.${index}.${input.name}` as const)
})}
{errors[tableName]?.[index][input.name] &&
<p className="bg-red-400 p-1">
{errors[tableName][index][input.name]?.message}
</p>
}
</td>
))}
{(min === undefined || min <= index) &&
<td onClick={() => remove(index)}><IoMdRemoveCircle className="text-red-600 text-2xl"/></td>
}
</tr>
))}
<tr>
<td onClick={() => append(inputBlueprint)} className="bg-green-500 border-gray-400 border-2"
colSpan={inputFields.length}>
<IoMdAdd className="m-auto"/>
</td>
</tr>
{errors[tableName] &&
<tr>
<td className="max-w-fit text-center">
{errors[tableName].message}
</td>
</tr>}
</tbody>
</table>
)
}
export default InputTable
Now, whenever I have only one element in the array it works just fine but when having more than one it crashes whenever an input field is emptied through typing. I don't really know how to explain it clearly so here's a gif showing it
My aim is to get the Data from an API call on first rendering of the page, store it in a state variable for further use. During the call, a loader keeps spinning and when call is successful, the loader disappears and the data is rendered on the screen using the state variable in which the response is saved.
Currently, I successfully make the call and get the data but when I try to store the data on a state variable, it remains undefined. I know that it is due to the fact that I have not initiated it with anything when I declared it.
My concern being when I set it later to the response of the API call then why is it undefined? Also if it is undefined then the loader would be running infinitely but in reality it stops and certain part of data is shown.
I have looked at various solution on Stack overflow and tried the following:
Check the state variable is not empty before rendering
used useLayoutEffect instead of useEffect
put the call function inside useEffect
Nothing works and the loader is stuck on loading.
Thank You.
import React, { useState, useEffect } from "react";
import * as S from "./Service.js";
import { Loader } from "./Loader.js";
function NeedHelp() {
let rspnse;
const [loader, setLoader] = useState(true);
const [data, setData] = useState(); // not setting any value
async function fetchData() {
rspnse = await S.getData();
setData(rspnse);
console.log("data :\n",data);
}
useEffect(() => {
setLoader(true);
fetchData();
setLoader(false);
}, []);
return (
<div className=" pt-3 p-1 mx-1 w-full">
{loader || typeof data === "undefined" ? (
<Loader />
) : (
data && (
<div>
<div id="first row" className="border p-2">
<span className="px-4 px-4 flex border">
<input
className="w-1/5 text-xs rounded py-1 px-1.5 placeholder-gray placeholder-opacity-75 focus:ring-0.5 focus:ring-blue focus:border-blue"
type="text"
placeholder="Filter..."
></input>
<div id="search_clear" className=" mx-1">
<button
onClick=""
className="text-white rounded px-1.5 py-1 mx-0.5 bg-blue transition duration-500 ease-in-out transform hover:translate-x-1 hover:scale-110 hover:bg-blue hover:shadow-lg"
>
Clear
</button>
</div>
<div className="self-center">
<p className="text-sm text-bgray ml-5">
Number of View: {data.data.length}
</p>
</div>
</span>
</div>
<div id="table">
<table className="table_auto w-full">
<thead>
<tr className="">
<th className=" "> Name</th>
<th className=" "> ID</th>
<td className=" "></td>
<td className=" "></td>
</tr>
</thead>
<tbody className="border">
<tr>
<td className="border">1</td>
<td className="border">2</td>
<td className="border">3</td>
<td className="border">4</td>
</tr>
</tbody>
</table>
</div>
</div>
)
)}
</div>
);
}
export default NeedHelp;
No reason to store rsponse as you have, and I cleaned the code up in a couple of other ways that aren't super notable, except maybe that loading will always be shown if no data is set. This should without any hitches, if it doesn't further debugging of what res is needs to be done:
import React, { useState, useEffect } from "react";
import * as S from "./Service.js";
import { Loader } from "./Loader.js";
function NeedHelp() {
const [data, setData] = useState(); // not setting any value
useEffect(() => {
(async () => {
setData(await S.getData());
})();
}, []);
return (
<div className=" pt-3 p-1 mx-1 w-full">
{!data ? (
<Loader />
) : (
<div>
<div id="first row" className="border p-2">
<span className="px-4 px-4 flex border">
<input
className="w-1/5 text-xs rounded py-1 px-1.5 placeholder-gray placeholder-opacity-75 focus:ring-0.5 focus:ring-blue focus:border-blue"
type="text"
placeholder="Filter..."
></input>
<div id="search_clear" className=" mx-1">
<button
onClick=""
className="text-white rounded px-1.5 py-1 mx-0.5 bg-blue transition duration-500 ease-in-out transform hover:translate-x-1 hover:scale-110 hover:bg-blue hover:shadow-lg"
>
Clear
</button>
</div>
<div className="self-center">
<p className="text-sm text-bgray ml-5">
Number of View: {data.data.length}
</p>
</div>
</span>
</div>
<div id="table">
<table className="table_auto w-full">
<thead>
<tr className="">
<th className=" "> Name</th>
<th className=" "> ID</th>
<td className=" "></td>
<td className=" "></td>
</tr>
</thead>
<tbody className="border">
<tr>
<td className="border">1</td>
<td className="border">2</td>
<td className="border">3</td>
<td className="border">4</td>
</tr>
</tbody>
</table>
</div>
</div>
)}
</div>
);
}
export default NeedHelp;
modify your code as below
const [loader, setLoader] = useState(false);
async function fetchData() {
setLoader(true);
rspnse = await S.getData();
setData(rspnse);
console.log("data :\n",data);
setLoader(false);
}
useEffect(() => {
fetchData();
}, []);
import React,{useState,useEffect} from 'react';
import "../Track.css";
const Tracker = () => {
const[data,setData]= useState([]);
const getCovidData = async() =>{
const res = await fetch('https://api.rootnet.in/covid19-in/stats/latest');
const actualData = await res.json();
console.log(actualData.regional);
setData(actualData.regional);
}
useEffect(() => {
getCovidData();
}, []);
return (
<>
<div className="conatiner-fluid mt-5">
<div className="main-heading">
<h1 className="mb-5 text-center"> <span className="font-weight-bold">INDIA</span> COVID-19 DASHBOARD</h1>
</div>
<div className="table-responsive">
<table className="table table-hover">
<thead className="thead-dark">
<tr>
<th> STATE</th>
<th> CONFIRMED</th>
<th> RECOVERED</th>
<th> DEATHS</th>
<th> ACTIVE</th>
<th> UPDATED</th>
</tr>
</thead>
<tbody>
{
data && data.map((curElem,ind,regional) => {
return(
<tr key={ind}>
<th> {curElem?.loc} </th>
<td> {curElem?.confirmedCasesIndian} </td>
<td> {curElem?.discharged} </td>
<td> {curElem?.deaths} </td>
<td> {curElem?.lastOriginUpdate} </td>
</tr>
)
})
}
</tbody>
</table>
</div>
</div>
</>
)
}
export default Tracker
I am not getting output of api values in the output page. Pls help as their may be the mistake in map function. pls share your views and and share solution if possible.
regional is inside data object.
{
"success": true,
"data": {
"summary": {...}
"unofficial-summary" : [...],
"regional" : [...]
...
}
}
You need to change setData(actualData.regional); as below
// ...
const getCovidData = async() =>{
const res = await fetch('https://api.rootnet.in/covid19-in/stats/latest');
const actualData = await res.json();
console.log(actualData.regional);
setData(actualData.data.regional);
}