I am noob on front-end world and could not find a solution for that I have a MainPanel component and I want to get data by using a service class method. The service class will have multiple functions and I will use them in different places.
Here is MainPanel code:
const [posts, setPosts] = useState({ blogs: [] });
const service = FetchCustomerService;
useEffect(() => {
const fetchPostList = async () => {
let customers = service.getCustomerList;
setPosts({ customers });
console.log(customers);
};
fetchPostList();
}, []);
And I want to create a separate service class for calls to backend:
export class FetchCustomerService {
getCustomerList = () => {
const { data } = await axios(
"https://jsonplaceholder.typicode.com/posts"
);
return data;
}
getAnotherFunction = () => {
}
}
export default FetchCustomerService;
How can I call service class method from MainPanel? There are some examples like giving the service class into main panel as props but isn't it possible to just call it like a Java class object etc calling like:
FetchCustomerService.getCustomerList();
You don't need a class for that, just export the functions you need from the file:
export async function getCustomerList() {
const { data } = await axios(
"https://jsonplaceholder.typicode.com/posts"
);
return data;
}
export function getAnotherFunction(){
...
}
import { getCustomerList } from 'yourFile';
...
useEffect(() => {
const fetchPostList = async () => {
const customers = await getCustomerList();
setPosts({ customers });
};
fetchPostList();
}, []);
Related
I'm using react-google-recaptcha to generate invisible ReCaptcha and I need to use the token in another const.
The token is generating correctly, but I don't know how to pass it on to another location. How should I do this?
const onTextSubmit = async () => {
let recaptchaToken;
if (recaptchaLoaded) {
recaptchaToken = await recaptcha.current.execute();
}
// How to export recaptchaToken?
};
I need to get the recaptchaToken and use it here:
const onSubmit: SubmitHandler<FormInput> = (data) => {
formCreateMutation.mutate({
data,
recaptchaToken,
});
};
The two const are in the same file, I'm using react to do that.
Thanks!!
You are not posting all code from the component but you can store the recaptchaToken value in react state like this:
export default function App() {
const [recaptchaToken, setRecaptchaToken] = useState(undefined);
const onTextSubmit = async () => {
if (recaptchaLoaded) {
const value = await recaptcha.current.execute();
setRecaptchaToken(value);
}
// How to export recaptchaToken?
};
const onSubmit: SubmitHandler<FormInput> = (data) => {
if (recaptchaToken) {
formCreateMutation.mutate({
data,
recaptchaToken,
});
}
};
return (
<div className="App">
<h1>{recaptchaToken}</h1>
</div>
);
}
I want to populate dropdown menu with data from Rest API. I tried this:
<Select id="country-helper">
{array.map((element) => (
<MenuItem value={element.code}>{element.country}</MenuItem>
))}
</Select>
I created this service with Axios:
export interface CountriesDTO {
country?: string;
code: string;
}
import axios, { AxiosResponse } from "axios";
import { CountriesDTO } from "./types";
const baseUrl = "http://localhost:8080/api";
export async function getCountries(): Promise<AxiosResponse<CountriesDTO[]>> {
return await axios.get<CountriesDTO[]>(
`${baseUrl}/merchants/onboarding/countries`
);
}
It's not clear how I can make the call into the React page. I tried this:
useEffect(() => {
const getData = async () => {
getCountries()
.then((resp) => {
console.log(resp.data);
})
.catch((error) => {
console.error(error);
});
};
}, []);
How I can populate the dropdown using the data from GET API call?
Just call your function getData from useEffect, you should also create state array to store your data.
const [array, setArray] = useState<CountriesDTO[]>([]); // <=== create state array
useEffect(() => {
getData(); // <=== call your function
}, []);
const getData = async () => {
getCountries()
.then((resp) => {
setArray(resp.data);
})
.catch((error) => {
console.error(error);
});
};
I'm looking for a way to have a dynamic route that displays for every document in a Firestore collection using Server-side Rendering.
For example, a document called foo would exist at test.com/foo under the [doc] page component. Any time a document is added, it should be able to be accessed through its respective URL.
I've tried this method but I haven't been able to get it to work.
I've also tried implementing getServerSideProps but have not had much success, any pointers would be appreciated.
Code from the method above as follows:
under pages/api/[doc].js
export default (req, res) => {
db.collection("docs")
.doc(req.query.name)
.get()
.then((doc) => {
res.json(doc.data());
})
.catch((error) => {
res.json({ error });
});
};
under pages/[shoal].jsx
import { useRouter } from "next/router";
import useSWR from "swr";
const fetcher = async (...args) => {
const res = await fetch(...args);
return res.json();
};
function Doc() {
const router = useRouter();
const { name } = router.query;
const { data } = useSWR(`/api/${name}`, fetcher);
if (!data) {
return "Loading...";
}
return (
<div>
<p>Title: {data.title}</p>
</div>
);
}
export default Doc;
You can try using getServerSideProps:
export const getServerSideProps = async (ctx) => {
const doc = await db.collection("docs").doc(ctx.query.id).get()
const data = doc.data()
if (!data) return { notFound: true };
return { props: { data } };
};
function Doc({data}) {
const router = useRouter();
const { name } = router.query;
if (!data) {
return "Loading...";
}
return (
<div>
<p>Title: {data.title}</p>
</div>
);
}
export default Doc;
Simple solution.
const { data } = useSWR(api ? '/api/${name}' : null, fetcher);
Conditionally fetch the data if your variable is defined, if not, don't pass a URL string, better yet; you can conditionally consider the fetcher for usage also.
const { data } = useSWR(name ? '/api/${name}' : null, name ? fetcher : null);
I'm learning Hooks with React and I'm trying to do a simple fetch to an API then I'm trying to save that data inside a Hook but It has not been possible for me.
import React, { useState, useEffect } from "react";
function useDogs() {
const [dogs, setDogs] = useState({
data: {}
});
useEffect(() => {
const fectData = async () => {
const data = await fetch("https://dog.ceo/api/breeds/image/random");
setDogs({ data: data.url });
console.log(data.url);
};
fectData();
}, []);
}
function Dogs() {
const dogs = useDogs();
console.log("dogs", dogs);
return <ul>{dogs} dogy</ul>;
}
export default Dogs;
In component Dogs() I'm having dogs as undefined
You aren't returning dogs from your useDogs hook.
(Also, to get at the response data, you need to await on .json() from the fetch response.)
import React, { useState, useEffect } from "react";
function useDogs() {
const [dogs, setDogs] = useState({
data: {},
});
useEffect(() => {
const getData = async () => {
const resp = await fetch("https://dog.ceo/api/breeds/image/random");
const data = await resp.json(); // <-- this
setDogs({ data });
console.log(resp, data);
};
getData();
}, []);
return dogs; // <-- this
}
function Dogs() {
const dogs = useDogs();
console.log("dogs", dogs);
return <ul>{dogs} dogy</ul>;
}
export default Dogs;
Custom Hooks are just javascript functions if you want to assign them to a variable you need to return something in your custom hook,
In some situations you need to set Something into your custom hook which you can do that by returning both value and setValue functions, for example in your case like below:
import React, { useState, useEffect } from "react";
function useDogs() {
const [dogs, setDogs] = useState({
data: {},
});
useEffect(() => {
const getData = async () => {
const resp = await fetch("https://dog.ceo/api/breeds/image/random");
const data = await resp.json(); // <-- this
setDogs({ data });
console.log(resp, data);
};
getData();
}, []);
return [dogs, setDogs]; // <-- this
}
and when you want to use it you just destructure it like this:
function Dogs() {
const [dogs, setDogs] = useDogs();
console.log("dogs", dogs);
return <ul>{dogs} dogy</ul>;
}
export default Dogs;
now you can read the data and also in future cases if you'ld like you can set the data too,
I am writing a client to talk to a server API in JavaScript. I have an OOP background but am trying to embrace modern EcmaScript.
So I started with this:
customerApi.js:
const baseUrl = "http://myapi";
export const getCustomers = () => { /* get customer code */ }
export const addCustomer = cust => {}
export const deleteCustomer = id => {}
All the functions use baseUrl.
Now I want to refactor so that the code that uses customerApi.js sets/passes in the baseUrl, and the only ways I have come up with are -
make it a class:
export default class customerApi {
constructor(baseUrl) {
this._baseUrl baseUrl;
}
}
Pass it into every method:
export const getCustomers = (baseUrl) => { /* get customer code */ }
export const addCustomer = (baseUrl,cust) => {}
export const deleteCustomer = (baseUrl,id) => {}
Wrap in a function:
const moduleFn = baseUrl => (
return {
getCustomers: () => { /* get customer code */ }
addCustomer: (cust) => {}
deleteCustomer: (id) => {}
}
)
export default moduleFn;
These are just examples.
What is the most common pattern to implement a "settable" variable on a module?
I would go with the function approach
export default function(baseUrl){
return Object.freeze({
getCustomers: () => { /* get customer code */ }
addCustomer: (cust) => {}
deleteCustomer: (id) => {}
})
}
This is because all the functions have closure on the baseUrl and no extra work is required.
Client code can simply
import yourmodule from 'yourmodule';
var derp = yourmodule('www.derp.com')