I am using multi avatar api to render random images on the UI, but I am getting the below-mentioned error. I also tried using promises to render the UI but failed to get the results.
Uncaught TypeError: The first argument must be one of type string,
Buffer, ArrayBuffer, Array, or Array-like Object. Received type
undefined
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import axios from "axios";
import { profilePicRoute } from "../utils/apiRoutes";
import { Buffer } from "buffer";
function ProfilePic() {
const api = "https://api.multiavatar.com";
const navigate = useNavigate();
const [profilePic, setProfilePic] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [selectedPofilePic, setSelectedPofilePic] = useState(undefined);
const toastStyles = {
position: "top-center",
};
const setProfilePicture = async () => {};
useEffect(() => {
const data = [];
for (let i = 0; i < 4; i++) {
const image = axios.get(`${api}/${Math.round(Math.random() * 1000)}`);
const buffer = Buffer(image.data);
data.push(buffer.toString("base64"));
console.log(data);
}
setProfilePic(data);
setIsLoading(false);
}, []);
return (
<div className="profilePage">
<h1>Pick your favorite profile picture</h1>
<div className="profilePics">
{profilePic.map((pic, index) => {
return (
<div
key={index}
className={`pic ${selectedPofilePic === index ? "selected" : ""}`}
>
<img
src={`data:image/svg+xml;base64,${pic}`}
alt="profile pic"
onClick={() => setSelectedPofilePic(index)}
/>
</div>
);
})}
</div>
<ToastContainer />
</div>
);
}
export default ProfilePic;
Since you were using the async you must have to use await keyword , otherwise it will return promises,and you should use the function inside the useEffect
import React, { useEffect, useState } from "react";
import { useNavigate } from "react-router-dom";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
import axios from "axios";
import { profilePicRoute } from "../utils/apiRoutes";
import { Buffer } from "buffer";
function ProfilePic() {
const api = "https://api.multiavatar.com";
const navigate = useNavigate();
const [profilePic, setProfilePic] = useState([]);
const [isLoading, setIsLoading] = useState(true);
const [selectedPofilePic, setSelectedPofilePic] = useState(undefined);
const toastStyles = {
position: "top-center"
};
useEffect(() => {
const setProfilePicture = async () => {
const data = [];
for (let i = 0; i < 4; i++) {
const image = await axios.get(
`${api}/${Math.round(Math.random() * 1000)}`
);
console.log(image);
const buffer = Buffer(image.data);
data.push(buffer.toString("base64"));
}
setProfilePic(data);
setIsLoading(false);
};
setProfilePicture();
}, []);
return (
<div className="profilePage">
<h1>Pick your favorite profile picture</h1>
<div className="profilePics">
{profilePic.map((pic, index) => {
return (
<div
key={index}
className={`pic ${selectedPofilePic === index ? "selected" : ""}`}
>
<img
src={`data:image/svg+xml;base64,${pic}`}
alt="profile pic"
onClick={() => setSelectedPofilePic(index)}
/>
</div>
);
})}
</div>
<ToastContainer />
</div>
);
}
export default ProfilePic;
Hope this code will help you.
Happy Coding :)
Related
Right now, I have this code (showing generic):
import {useState} from 'react';
const parentComponent = () => {
const [show, setShow] = useState(false);
return
(<>
<childComponent setShowDependent={() => setShow(true)} />
{ show && <dependentComponent /> }
</>);
}
const childComponent = ({setShowDependent}) => {
return <Button onClick={setShowDependent} />;
}
and I am getting the warning in react dev tools:
Warning: Cannot update a component (`parentComponent`) while rendering a different component (`childComponent`).
and it is not working properly. What am I doing wrong?
React component name must start with an uppercase letter
import {useState} from 'react';
const ParentComponent = () => {
const [show, setShow] = useState(false);
return (<>
<ChildComponent setShowDependent={() => setShow(true)} />
{ show && <DependentComponent /> }
</>);
}
const ChildComponent = ({setShowDependent}) => {
return <Button onClick={setShowDependent} />;
}
On this case I am trying to show the "_id".
I made the code based on this video.
But by just looking at his API I can see that his data is little different, how can I adapt it to work with my API
import "./App.css";
import axios from "axios";
import { useEffect, useState } from "react";
const App = () => {
const [leitura, setLeitura] = useState([]);
const getLeituraData = async () => {
try {
const data = await axios.get(
"https://estufaarduino.herokuapp.com/sistema/leituras"
);
console.log(data.data);
setLeitura(data.data);
} catch (e) {
console.log(e);
}
};
useEffect(() => {
getLeituraData();
}, []);
return (
<div className="App">
{leitura.map((item) => {
return <p>{item._id}</p>;
})}
</div>
);
};
export default App;
I'd like to pagination news, or use infinite scroll, but as the site is built then served as static files, I'm not sure the best way to go about this?
Is it possible to do without using apollo or react-query?
I did try react-query but couldn't get it to see my datoCMS endpoint.
(Update: comment below about promise)
import React from 'react'
import { useQuery } from 'react-query'
import gql from 'graphql-tag'
import { GraphQLClient, request } from 'graphql-request'
export const useGQLQuery = (key, query, variables, config = {}) => {
const endpoint = `https://graphql.datocms.com/`
const client = new GraphQLClient(endpoint, {
headers: {
authorization: `Bearer MY_TOKEN_HERE`
}
});
// use await to wait until promise has been fulfilled
const fethData = async () => await request(endpoint, client, query, variables)
return useQuery(key, fethData, config); // useQuery from react-query
};
const GET_ALL_NEWS_CONTENT = gql`
query {
allNews {
slug
id
title
}
}
`;
const AllNews = () => {
// Fetch data from custom hook that uses React-Query
const { data, isLoading, error } = useGQLQuery('allNews', GET_ALL_NEWS_CONTENT)
console.log(data)
if (isLoading) return <div>Loading…</div>
if (error) return <div>Something went wrong…</div>
return (
<>
<div className="generic-page">
<h2>All News</h2>
<div>
{data.allNews.map(news => (
<div key={news.title}>{news.title}</div>
))}
</div>
</div>
</>
)
};
export default AllNews;
With a little help from datoCMS and the react-query community, here is the solution! …
import React, { useState } from 'react'
import { useQuery } from 'react-query'
import gql from 'graphql-tag'
import { GraphQLClient } from 'graphql-request'
export const useGQLQuery = (key, query, variables) => {
const endpoint = `https://graphql.datocms.com/`
const client = new GraphQLClient(endpoint, {
headers: {
authorization: `Bearer MY_TOKEN_HERE`,
}
});
return useQuery(
key, () => client.request(query, variables),
{ keepPreviousData: true }
); // useQuery from react-query
};
const GET_ALL_NEWS_CONTENT = gql`
query GetAllNewsContent ($first: IntType = 10, $skip: IntType = 0) {
allNews(first: $first, skip: $skip, orderBy: _createdAt_DESC) {
id
title
slug
}
}
`;
export default function AllNews({ newscount }) {
const first = 5
let [skip, skipNews] = useState(0)
// Fetch data from custom hook that uses React-Query
const { data, status } = useGQLQuery(
['allNews', skip],
GET_ALL_NEWS_CONTENT,
{ skip, first }
);
const itemCount = Math.ceil(newscount / first);
return (
<div className="generic-page">
<button className="example_b"
onClick={() => skipNews(old => Math.max(old - 5, 0))}
disabled={skip === 0}
>
<span>Previous Page</span>
</button>{' '}
<button className="example_f"
onClick={() => skipNews(old => Math.max(old + 5, 0))}
// Disable the Next Page button when the next skip would be higher than the meta count
disabled={skip + 5 > newscount}
>
<span>Next Page</span>
</button>
<h2>All News</h2>
<p>Page {skip / 5 + 1} of {itemCount}</p>
{status === 'loading' && (
<div>Loading…</div>
)}
{status === 'error' && (
<div>Something went wrong…</div>
)}
{status === 'success' && (
<div>
{data.allNews.map(news => (
<div key={news.title}>{news.title}</div>
))}
</div>
)}
</div>
)
};
when i use the .map to print all companies in my page gives the following issue (TypeError cias.map is not a function):
Error
Code:
import fetch from 'isomorphic-unfetch'
import Link from 'next/link'
import { Container } from '../../../styles/pages/container'
import React from 'react'
import { GetStaticProps } from 'next'
import { Cias } from '../../../../model/cias'
export interface CiasProps {
cias: Cias[]
}
// eslint-disable-next-line #typescript-eslint/explicit-module-boundary-types
export default function CiasBrazil({ cias }: CiasProps) {
return (
<Container>
{console.log(cias)}
<ul>
{cias.map(cia => {
;<li className="cia" key={cia.Code}>
<Link
href="/companies/brazil/[id]"
as={`/companies/brazil/${cia.Code}`}
>
<a>
<span>{cia.Name}</span>
</a>
</Link>
</li>
})}
</ul>
</Container>
)
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
const res = await fetch('http://localhost:3000/api/infocadcias')
const cias = await res.json()
return { props: { cias } }
}
Cias interface:
export interface Cias {
Code: number
Name: string
}
API:
API
Your data is like
{cias: []}
So to access cias,
const data = await res.json();
const cias = data.cias;
// ....
In the bellow example, how can I pass imageAsUrl.imgUrl from the Child component (ImageUpload) to the parent component (UpdateCard).
CHILD Component
import React, { useState, useEffect } from 'react';
import { storage } from '../firebase';
const ImageUpload = () => {
const allInputs = { imgUrl: '' };
const [imageAsUrl, setImageAsUrl] = useState(allInputs);
const [image, setImage] = useState(null);
const handleChange = (e) => {
if (e.target.files[0]) {
setImage(e.target.files[0]);
}
};
useEffect(() => {
if (image) {
const uploadTask = storage.ref(`images/${image.name}`).put(image);
uploadTask.on(
'state_changed',
(snapshot) => {},
(error) => {
console.log(error);
},
() => {
storage
.ref('images')
.child(image.name)
.getDownloadURL()
.then((fireBaseUrl) => {
setImageAsUrl((prevObject) => ({
...prevObject,
imgUrl: fireBaseUrl,
}));
});
}
);
}
}, [image]);
return (
<>
<label className='custom-file-upload'>
<input type='file' onChange={handleChange} />
</label>
<img src={imageAsUrl.imgUrl} alt='sample' />
</>
);
};
export default ImageUpload;
PARENT Component
import React, { useState } from 'react';
import firebase from '../firebase';
import ImageUpload from './ImageUpload';
const UpdateCard = ({ card }) => {
const [originalText, setOriginalText] = useState(card.originalText);
const [translatedText, setTranslatedText] = useState(card.translatedText);
const onUpdate = () => {
const db = firebase.firestore();
db.collection('FlashCards')
.doc(card.id)
.set({ ...card, originalText, translatedText });
timeOutScroll();
};
return (
<>
<div>
{card.imageURL ? (
<img src={card.imageURL} alt='' className='img' />
) : (
<textarea
className='upload-textarea'
value={originalText}
onChange={(e) => {
setOriginalText(e.target.value);
}}
/>
)}
<ImageUpload />
</div>
<textarea
value={translatedText}
onChange={(e) => {
setTranslatedText(e.target.value);
}}
/>
<button onClick={onUpdate}>Update</button>
</>
);
};
export default UpdateCard;
Inside parent,You can define a callback function as prop ref to be called inside the child.
const ImageUpload = ({getURLtoParent}) =>{ <--------------------
const [imageAsUrl, setImageAsUrl] = useState(allInputs);
useEffect(() => {
uploadTask.on(
..............
...
);
if(imageAsUrl.imgUrl !== '')
getURLtoParent(imageAsUrl.imgUrl) <-----------------------
},[image])
}
const UpdateCart = () => {
const[imgURL,setimgURL] = useState(null)
return (
......
<ImageUpload getURLtoParent={ (url) => setimgURL(url) } /> <----------------
.........
)
}