how to reverse fetch images from nasa APOD api in react - javascript

** I fetched content from API with this code**
import React from "react";
import styles from "./Space.module.css";
import {useState,useEffect} from "react";
function Space() {
const [photoData,setPhotoData]=useState(null);
useEffect(()=>{
fetchPhoto();
async function fetchPhoto(){
const res = await fetch(`https://api.nasa.gov/planetary/apod?api_key=hETQq0FPsZJnUP9C3sUEFtwmJH3edb4I5bghfWDM`);
const data=await res.json();
setPhotoData(data);
console.log(data);
}
},[]); //empty array for running only once then empty array for that
if (!photoData) return <div />;
return (
<>
<div className={styles.space}>
{photoData.media_type === "image" ? (
<img
src={photoData.url}
alt={photoData.title}
className={styles.space}
/>
) : (
<iframe
title="space-video"
src={photoData.url}
frameBorder="0"
gesture="media"
allow="encrypted-media"
allowFullScreen
className={styles.space}
/>
)}
<div>
<h1>{photoData.title}</h1>
<p className={styles.space.date}>{photoData.date}</p>
<p className={styles.space.explanation}>{photoData.explanation}</p>
</div>
</div>
</>
);
}
export default Space;
and output of this code is like this
and I want Button here with next and then that will show previous day images
so can anyone tell me how to reverse that means after clicking on the next button by reversing the previous day images will show because NASA APOD(astronomy picture of the day )daily shown to all users like that is updated daily I know we can reverse that but can anyone tell me how to do that?

You can use date query parameter of apod api to get data for a specific date. This has default value today. Date needs to be in YYYY-MM-DD format. See apod section at https://api.nasa.gov/
If you want to request data for 2 January 2021 you'll have to send request to this :
https://api.nasa.gov/planetary/apod?date=2021-01-02&api_key=hETQq0FPsZJnUP9C3sUEFtwmJH3edb4I5bghfWDM
Note the date parameter
To get the previous day date use :
let today = new Date();
let yesterday = new Date();
yesterday.setDate(today.getDate() - 1);
console.log(yesterday.toString());
for formatting date in YYYY-MM-DD format see this question.
In onClick function of your button you'll make this http request and then change state with setPhotoData function.

Related

How do I edit each individual array element in v-for loop with Vue3?

Basically I have this calendar row with date info on each element:
I'm trying to stop that loop of single data so that each calendar item has it's own data about the current and the next days.
The first calendar element should always display the current day, the rest of the items are the remaining days
Template
<template>
<div class="wrapper">
<div class="calendar-wrapper">
<div class="calendar-row"
v-for="(day, idx) in dayArr"
:key="idx"
>
<div
id="card"
class="day-card unactive"
#click="test(idx)"
>
<div class="card-info">
<p class="name">{{ dayOfWeek }}</p>
<p class="day">
{{ currDay }}
</p>
</div>
<div class="dot-wrapper">
<div class="dot-status undone" />
<div class="dot-status undone" />
</div>
</div>
</div>
</div>
</div>
</template>
Script
setup() {
const moment = require('moment')
const m = moment
// Get the remaining month days starting from today:
const daysRemainingThisMonth = moment().endOf('month').diff(moment(), 'days');
// Turn the remaining days into an array for future rendering in the Template
let dayArr = Array(daysRemainingThisMonth)
// Get the index of a clicked calendar item:
const test = (idx) => {
console.log(idx + 1);
}
// Get the current day:
const currDay = m().format('D')
// Get the current week day:
const dayOfWeek = m().format('dddd')
}
I believe that there is a way to somehow access each calendar element and give it it's own data, but I have no idea how
I've changed your code using moment features and it shows correctly in this link.
As you see I use moment().add(<countingOfDiffrenceFromToday>, 'day') to reach the exact day and push it to the array and use it in v-for loop.

How to implement percentage increase data from API in React?

I have this problem where I need to fetch data from API and calculate the percentage increase within a certain number of days. Here's the code below...
function Card() {
const [newEnrollments, setNewEnrollments] = useState("");
const getNewEnrollments = async () => {
// API call
};
useEffect(() => {
getNewEnrollments();
}, []);
// data returned from API
// { "new_enrollments": 12248 }
return (
<Wrapper>
<div className="card1">
<div className="user">
<HowToRegRoundedIcon className="icon" />
</div>
<div className="card-info">
<h3>NEW ENROLLMENTS</h3>
<h4>450</h4>
<p>
<BorderLinearProgress variant="determinate" value={90} />
<span> 90% Increase in 90 Days</span>
</p>
</div>
</div>
</div>
</Wrapper>
);
}
I want to be able to change the hard-coded values in h4(as the value from API), the progress bar, and the span value within 90 days. such that as more data is being updated the values dynamically changes and also the percentage increase.
If I'm understanding your question correctly, then
<h4>{data_returned_from_api["new_enrollments"]}</h4>
and
<span> {(data_returned_from_api["new_enrollments"] / old_data["new_enrollments"]) * 100}% Increase in 90 Days</span>
should do the trick. You should probably also add some try-catch-statements so that it doesn't crash if the data is missing.
Edit: Obviously, you need to be able to get hold of both the new value and the old value in order to use them. If you don't have both those values, then it is impossible.

React-Calendar month view change

I am using React-Calendar and I am unable to change the month bu clicking the arrows (back/ forward) in the navigation panel, where the month name is displayed. My code:
...
const onActiveStartDateChangeHandler = ({ activeStartDate, value, view }) => {
console.log("vv:", activeStartDate, value, view);
};
...
return (
<div className="popupFormSelector arrowLft pb-8">
<h2 className="text-center font-bold mt-7 mb-5">Set a deadline</h2>
<Delete classes="right-5 top-5" onClickHandler={toggleCalendar} />
<Calendar
activeStartDate={teamStartDate}
calendarType="US"
defaultView="month"
maxDetail="month"
maxDate={endDate}
minDate={teamStartDate}
next2Label={null}
onActiveStartDateChange={onActiveStartDateChangeHandler}
onChange={onChangeHandler}
prev2Label={null}
selectRange={false}
showDoubleView={false}
showFixedNumberOfWeeks={false}
showNavigation={true}
showNeighboringMonth={true}
tileClassName={tileClasses}
tileDisabled={({ activeStartDate, date, view }) =>
date < teamStartDate || date > endDate
}
value={new Date()}
view={"month"}
/>
From console.log on handler for onActiveStartDateChange, I can see that the date is changed in the log, however, the view stays at the current month. What am I doing wrong?
The month view doesn't change because it is tied to the value you provided here:
activeStartDate={teamStartDate}
As stated in the docs, this initiates a "controlled" behavior:
activeStartDate The beginning of a period that shall be displayed. If you wish to use React-Calendar in an uncontrolled way, use defaultActiveStartDate instead.
So either use defaultActiveStartDate instead of activeStartDate if it matches your use case, or you could simply update the value of teamStartDate in the method, like this:
const onActiveStartDateChange = ({activeStartDate}) => teamStartDate = activeStartDate

How to implement an array increment function within JSX code using React.js JavaScript

I'm trying to develop a React program that changes information in a component each time the button "rectForward" or "rectBackward" is pressed. I'm passing the information in the form of an array of objects into my Body component from "importData" as seen below. That data is then converted into each object's indvidual data pieces through the map functions listed directly after render() is called. What I want to happen when the rectForward button is pressed is for the "text1" array value in Column1 to incrament by 1. The same happens when rectBackward is pressed, but I want the value to decrement. My primary difficulty is the syntax. As you can see in the statement onClick={Column1.text1=text1val[++], this was my first attempt at implementing this functionality, but the syntax is definitely incorrect. I was wondering if I could get some help formatting this
import React from "react";
import "./Body.css";
import Column1 from "./Body/Column1/Column1";
import "./Buttons.css";
import Column2 from "./Body/Column2/Column2";
import myData from "./myData";
class Body extends React.Component {
constructor() {
super()
this.state = {
importData: myData
}
}
render() {
var ID = this.state.importData.map(item => item.id)
var text1val = this.state.importData.map(item => item.text1)
var text2val = this.state.importData.map(item => item.text2)
var text3val = this.state.importData.map(item => item.text3)
return(
<div className="mainBody">
<div className="backPain">
<div className="holder">
<Column1 key={ID[0]} text1={text1val[0]}>
</Column1>
<div className="rectHolder">
<div className="rectForward" onClick={Column1.text1=text1val[++]}
<h2>Next</h2>
</div>
<div className="rectBackward">
<h2>Prev</h2>
</div>
</div>
<Column2 key={ID[0]} text2={text2val[0]} text3={text3val[0]}>
</Column2>
</div>
</div>
</div>
)
}
}
export default Body;
Thanks so much!
Simple thing i will do is keep an index in state. Than pass a function to next and prev which takes care of changing this index. and will show the values based on current state.
this.state = {
currentIndex : 0
}
HandleCurrentIndex(type){
if(type === 'inc'){
this.setState({currentIndex: this.state.currentIndex++})
} else {
this.setState({currentIndex: this.state.currnIndex-1 })
}
}
<div className="rectForward" onClick={()=>this.HandleCurrentIndex("inc")}>
<h2>Next</h2>
</div>
<div className="rectBackward" onClick={()=>this.HandleCurrentIndex('dec')}>
<h2>Prev</h2>
</div>
On side note:- This is just and example in product you should take care of index going below zero as well index exceeding limits of your data. which in turn will show undefined values. simple thing you should do is whenever it goes out of limit just reset it to default value ( 0 )

Passing html element value to composeWithTracker in React

This Meteor code uses React. When user fills in an input box with id myVal, click a button. The input box value gets sent to the server via a method, the server updates the collection vehicles.
It then needs to take that input from user and use that as query to collection.findOne in myfile.jsx. It failed to pass the user input myVal from html input element.
How can it be done? Thanks
// -------------------- myfile.jsx -------------------
const renderWhenData = ( cars ) => {
if ( cars ) {
return <span>{ cars.description }</span>;
}
};
const Info = ( { cars } ) => (
<p>{ renderWhenData( cars ) }</p>
);
const composer = (props, onData) => {
const subscription = Meteor.subscribe('vehicles');
if (subscription.ready()) {
let myVal = document.getElementById('myVal').value;
console.log(myVal); // <------------------ nothing is printed out
const cars = Vehicles.findOne({name: myVal});
onData(null, {cars});
}
};
const Container = composeWithTracker(composer)(Info);
ReactDOM.render(<Container />, document.getElementById('react-info'));
// --------------------- events.js -----------------------
document.getElementById('startButton').addEventListener('click', () => {
const myVal = document.getElementById('myVal').value;
Meteor.call('startInfo', myVal); // <---------- updates server collection
});
<!--main.html-->
<head>
</head>
<body>
<form action="submit">
<input type="text" id="myVal">
<div id="react-info"></div>
</form>
<footer>
<button id="startButton">START</button>
</footer>
</body>
The question is a bit academic. There are better ways to handle this in React. But, since you are using Meteor, this can be done with some Tracker operations.
First define a tracker dependency:
export const textboxDep = new Tracker.Dependency;
Whenever the textbox value changes, trigger the changed event.
textboxDep.changed();
Within the composer, use
textboxDep.depend();
If the composer is written well, when the tracker dependency is invalidated, the whole functional container component runs again. And you should see the value of the textbox there.
Right now, when the value of the textbox is changed, since it is not reactive, the container does not re-render itself.

Categories

Resources