How to get an image from Directus? - javascript

I need to display images from directus
import React, { useEffect, useState } from 'react'
import { fetchArticles } from './async/fetchArticels'
const FileUpload = () => {
const [articles, setArticles] = useState([])
useEffect(()=>{
fetchArticles().then(data => setArticles(data))
}, [])
return (
<div>
{articles.map(article =>
<div>
<h3>{article.title}</h3>
<img src={article.image} alt="img" />
</div>
)}
</div>
)
}
export default FileUpload
code
import axios from "axios"
export const fetchArticles = async () => {
const {data} = await axios.get('http://localhost:8055/items/articles')
console.log(data.data)
return data.data
}
from the directus I get this data
I read about the blob method, but I can't get it.
What should I do?

From the Directus Docs:
You can consistently access [your files/images] via the API using the following URL.
example.com/assets/<file-id>
example.com/assets/1ac73658-8b62-4dea-b6da-529fbc9d01a4
Reference: https://docs.directus.io/reference/files/#accessing-an-file
For You
As you're wishing to display images in the browser, you will likely want something like this.
<img src={"//example.com/assets/" + article.image}" alt={article.title} />

Related

react axios URL concatenation returns 404 not found

I am trying to display dynamic data based on record id coming from useParams hook variable id. But when I concatenated the id value, it returns not found 404 error. Although the id value is returned as valid id when I console it, the concatenation doesn't work.
Here is my code
import React, { useEffect, useRef, useState } from "react";
import SignaturePad from "react-signature-canvas";
import offer from "./assets/offer.PNG";
import { Document, Page } from "react-pdf";
// Import the main component
import { Viewer } from "#react-pdf-viewer/core"; // install this library
// Plugins
import { defaultLayoutPlugin } from "#react-pdf-viewer/default-layout"; // install this library
// Import the styles
import "#react-pdf-viewer/core/lib/styles/index.css";
import "#react-pdf-viewer/default-layout/lib/styles/index.css";
// Worker
import { Worker } from "#react-pdf-viewer/core"; // install this library
import axios from "axios";
import { useParams } from "react-router-dom";
const Signature = (props) => {
const id = useParams();
const [numPages, setNumPages] = useState(null);
const baseURL = "http://127.0.0.1:8000/rent/" + id;
const [datas, setData] = useState([]);
useEffect(() => {
axios
.get(baseURL)
.then((response) => {
setData(response.data);
})
.then(
(response) => {},
(err) => {
console.log("No Data To Show");
}
)
.catch((err) => {
return false;
});
}, []);
// Create new plugin instance
const defaultLayoutPluginInstance = defaultLayoutPlugin();
console.log(docId);
return (
<div className="p-10 flex flex-col space-y-24 font-serif justify-center items-center">
<img src={imgg} />
{datas?.file && (
<>
<Worker workerUrl="https://unpkg.com/pdfjs-dist#2.6.347/build/pdf.worker.min.js">
<Viewer
fileUrl={datas?.file}
plugins={[defaultLayoutPluginInstance]}
/>
</Worker>
</>
)}
</div>
);
};
export default Signature;
Here is the value of id which is dynamically changing.
But when I pass the value of id as follows it works fine.
const baseURL =
"http://127.0.0.1:8000/rent/ce779e1d-3afb-4aa7-82e8-5bf74c4af0a7";
But when I concatenate the id variable it returns 404 not found error.
const baseURL =
"http://127.0.0.1:8000/rent/"+id;
What's my mistake here?
useParams hook of React Router returns an object with params.
You should to use something like that:
const { id } = useParams();
in the case if your params is called id.
More you can see here, in the documentation: https://v5.reactrouter.com/web/api/Hooks/useparams

React API not showing the data

I am not able to retrieve content from API every time I reload my page it shows error, please see the attached image, I wanted to find the weather details using Weather API and right now I am using static latitude and longitude.
import React, { useState, useEffect } from "react";
import axios from "axios";
import { FaRegSun } from "react-icons/fa";
import "./stylesheets/stylesheets.css";
function WeatherApp1() {
const [weatherData2, setWeatherData2] = useState({});
const API_endpoint2 = `https://api.openweathermap.org/data/2.5/onecall?`;
const API_key = `2a63c27d8ba0b0d14c9e5d59f39ee1ba`;
useEffect(() => {
async function getSecondObject() {
const response = await axios.get(
`${API_endpoint2}lat=28.4360704&lon=77.021184&units=metric&appid=${API_key}`
);
setWeatherData2(response.data);
}
getSecondObject();
}, []);
return (
<div className="mainDiv">
<div className="heading">
<h1>
<FaRegSun /> Weather
</h1>
</div>
{weatherData2.current.temp}
</div>
);
}
export default WeatherApp1;
https://i.stack.imgur.com/oqr7i.jpg
The problem with your code is that you're trying to render {weatherData2.current.temp} before the data is returned from the weather API and that's why your weatherData2 will be undefined while rendering.
You can add a loading state for checking if the data is rendering or already rendered.
You can try below code:
import React, { useState, useEffect } from "react";
import axios from "axios";
import { FaRegSun } from "react-icons/fa";
import "./stylesheets/stylesheets.css";
function WeatherApp1() {
const [loading, setLoading] = useState(true) // Loading state
const [weatherData2, setWeatherData2] = useState({});
const API_endpoint2 = `https://api.openweathermap.org/data/2.5/onecall?`;
const API_key = `2a63c27d8ba0b0d14c9e5d59f39ee1ba`;
useEffect(() => {
async function getSecondObject() {
const response = await axios.get(
`${API_endpoint2}lat=28.4360704&lon=77.021184&units=metric&appid=${API_key}`
);
setWeatherData2(response.data);
setLoading(false) // Setting the loading state to false after data is set.
}
getSecondObject();
}, []);
return (
<div className="mainDiv">
<div className="heading">
<h1>
<FaRegSun /> Weather
</h1>
</div>
{/* Checking for loading state before rendering the data */}
{loading ? (
<p>Loading...</p>
) : (
weatherData2.current.temp
)}
</div>
);
}
export default WeatherApp1;

Multiple API handling through Axios in react application

When I have Two APIs and one for cats data and one for cats image, how can I populate images and data from two APIs in one component using hooks through Axios call?
CodeSandbox
CatsList.js
import React, {useState, useEffect} from 'react'
import {baseUrl} from './services/mainApi';
import axios from 'axios';
export default function CatsList() {
const [data, setData] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios(
`${baseUrl}breeds`,
);
setData(result.data);
};
fetchData();
}, []);
return (
<ul className="row">
{data.map(item => (
<li className="col-md-3 list-item" key={item.id}>
<a href={item.wikipedia_url}>
<h2>{item.name}</h2>
<p>{item.origin}</p>
<p>{item.description}</p>
</a>
</li>
))}
</ul>
);
}
mainApi.js
import axios from 'axios';
export const baseUrl = 'https://api.thecatapi.com/v1/'
export const catsImage = `${baseUrl}/images/search?breed_id=abys`
You'll need to make a a request per cat to get the cats image, before setting data e.g.
const fetchData = async () => {
const result = await axios(
`${baseUrl}breeds`,
);
const catImageResponses = Promise.all(
result.data.map(cat => axios(buildCatImageUrl(cat)))
)
// handle catImageResponses, correlating them with result.data (cats), then set state
};
fetchData();
You'll need to correlate your cat images with your cats before setting your state, and you'll need to build the cat image url dynamically based on the cat, at the minute its hardcoded.

How do I print the promise value from a post request? (ReactJs)

I've been trying to figure out how to access the promise value passed back from the POST request, but so far the solutions I've seen on here I can't get my head round how to implement in a functional component not using .then.
I've tried .stringify and .text , but no difference. It's still only console logging the promise.
Button.jsx
import React, { useState } from 'react';
import axios from 'axios';
import getResponse from '../Handler/getResponse.jsx'
import getToken from '../Handler/getToken.jsx'
import './Button.css';
const Button = ({selectedIcon}) => {
const [selected] = selectedIcon;
const [xappToken] = useState(getToken());
console.log(xappToken);
return(
<div className="buttonBlock">
<span className="btn">
<input className="btn-outline" type="button" value="Press Me" onClick={ () => getResponse(xappToken) }/>
</span>
</div>
);
}
export default Button
getToken.jsx
export default async function getToken(){
try {
const response = await axios.post('https://api.artsy.net/api/tokens/xapp_token', {
client_id: 'some-client-id',
client_secret: 'some-client-secret'
});
console.log('👉 Returned data:', response.data.token);
return response.data.token;
} catch (e) {
console.log(`😱 Axios request failed: ${e}`);
return "Error";
}
}
That's because getToken is a promise. You can do this:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import getResponse from '../Handler/getResponse.jsx'
import getToken from '../Handler/getToken.jsx'
import './Button.css';
const Button = ({selectedIcon}) => {
const [selected] = selectedIcon;
const [xappToken, setXappToken] = useState(null);
useEffect(() => {
getToken().then(token => setXappToken(token))
}, [])
console.log(xappToken)
return(
<div className="buttonBlock">
<span className="btn">
<input className="btn-outline" type="button" value="Press Me" onClick={ () => getResponse(xappToken) }/>
</span>
</div>
);
}
export default Button
if i remember correctly
since you're getting a promise your gonna have to await the response as well.
you have to json() your response and store it into something else
then console.log the new result
for example
const result = await response.json()
console.log(result)
Try this one:
import React, { useState } from 'react';
import axios from 'axios';
import getResponse from '../Handler/getResponse.jsx'
import getToken from '../Handler/getToken.jsx'
import './Button.css';
const Button = async ({selectedIcon}) => {
const [selected] = selectedIcon;
const [xappToken] = useState(await getToken());
console.log(xappToken);
return(
<div className="buttonBlock">
<span className="btn">
<input className="btn-outline" type="button" value="Press Me" onClick={ () => getResponse(xappToken) }/>
</span>
</div>
);
}
export default Button
I guess you also need to do an async await in the Button.jsx:
const Button = async ({ selectedIcon }) => {
const [selected] = selectedIcon;
const [xappToken] = useState(await getToken());
console.log(xappToken);
};
Since getToken is well, technically a promise. So you need to do an await before accessing the value of that.

Easy Peasy state managment - How to fetch and pass data correctly?

I am using Easy Peasy State management for React. I would like to create multiple Axios call from one store location and import it in each page there where I need to show the correct data. I am trying to fetch a JSON placeholder data for example and use that inside a component to push it to the state using Hooks.
But I get the following error:
model.js:14 Uncaught (in promise) TypeError: actions.setTodos is not a function
at model.js:14
Can someone help me out? What am I doing wrong?
My code for the store (model.js):
import { thunk } from 'easy-peasy';
export default {
todos: [],
fetchTodos: thunk(async actions => {
const res = await fetch(
'https://jsonplaceholder.typicode.com/todos?_limit=10'
);
const todos = res.json();
actions.setTodos(todos);
}),
};
My Page component Contact:
import React, { useState, useEffect } from 'react';
import { useStoreActions } from 'easy-peasy';
import ReactHtmlParser from 'react-html-parser';
import { API_URL } from 'constants/import';
// import axios from 'axios';
const Contact = () => {
const [contactPage, setContactPage] = useState([]);
const { page_title, page_content, page_featured_image } = contactPage;
const fetchTodos = useStoreActions(actions => actions.fetchTodos);
useEffect(() => {
fetchTodos();
}, []);
return (
<section className="contact">
<div className="page">
<div className="row">
<div className="col-xs-12">
<h3 className="section__title">{page_title}</h3>
{ReactHtmlParser(page_content)}
{page_featured_image && (
<img src={API_URL + page_featured_image.path} />
)}
</div>
</div>
</div>
</section>
);
};
export default Contact;
You need to use action.
import { action, thunk } from "easy-peasy";
export default {
fetchTodos: thunk(async (actions, payload) => {
const res = await fetch(
"https://jsonplaceholder.typicode.com/todos?_limit=10"
);
const todos = res.json();
actions.setTodos(todos);
}),
todos: [],
setTodos: action((state, payload) => {
console.log("---->>> payload!")
state.todos = payload
}),
};
I usually use it like this, it works perfectly for me.

Categories