I am using openweathermap to display weather reports. Everything is working fine but there is a problem with the icon.
The JSON response code is:
Array
(
[city] => Array
(
[id] => 1271476
[name] => Guwahati
[coord] => Array
(
[lon] => 91.751
[lat] => 26.1862
)
[country] => IN
[population] => 899094
)
[cod] => 200
[message] => 0.0630711
[cnt] => 1
[list] => Array
(
[0] => Array
(
[dt] => 1495688400
[temp] => Array
(
[day] => 33
[min] => 24.89
[max] => 33.82
[night] => 24.89
[eve] => 30.6
[morn] => 33
)
[pressure] => 1013.02
[humidity] => 90
[weather] => Array
(
[0] => Array
(
[id] => 500
[main] => Rain
[description] => light rain
[icon] => 10d
)
)
[speed] => 3.92
[deg] => 88
[clouds] => 24
[rain] => 2.73
)
)
)
Now how can I display the icon: [weather][0][icon] => 10d?
What is 10d & how can I get the URL of the icon?
Well, I know a way using jQuery.
<div id="icon"><img id="wicon" src="" alt="Weather icon"></div>
At the HTML above you see the unique thing missing is the src attribute, so let's fill it with some jQuery and JavaScript.
You may create a variable to hold the icon code provided by the API like:
var iconcode = a.weather[0].icon;
After it you should concatenate this var iconcode with the url that contains the icons, like:
var iconurl = "http://openweathermap.org/img/w/" + iconcode + ".png";
Finally just change src attribute in the DOM by doing this:
$('#wicon').attr('src', iconurl);
You can get OpenWeatherMap API icons through this link. All you need to do is that moderate the icon id given in bold below in this link. You can change 10d with any icon id that you need.
http://openweathermap.org/img/w/10d.png
For more information, You can read here OpenWeatherMap Icons
So I spent a lot of time solving this problem. This answer is for pure HTML and JavaScript and if you don't want to use jquery.
1- Include the "icons" file in your program: openweatherAPI Icons integration
2- In your index.html :
<div class="weather-icon"><img src="icons/unknown.png" /></div>
3- In your JavScript file(follow these 3 steps in your JS code) :
1st Step: let locationIcon = document.querySelector('.weather-icon');
2nd Step: const {icon} = data.weather[0];
3rd Step(not in code format, as it was making thebackticks part disappear):
locationIcon.innerHTML = <img src="icons/${icon}.png">;
Worked just fine for me.
Happy building.
the src of the icon would be like this:
http://openweathermap.org/img/wn/10d#2x.png
see Weather icons
This code works for me in React Native:
const icon = wInfo.weather[0].icon; // For instance "09d"
<Image source={{ uri: ``http://openweathermap.org/img/w/${icon}.png`` }} />
Thank you all very much! I am a very beginning Flutter programmer and wanted to display the Icon in the Weatherapp, we made on course with Angela Yu.
I did this in Flutter:
String weerImageString;
weerImageString = weatherData['weather'][0]['icon'];
and then were I wanted it to display, I did:
Image.network('http://openweathermap.org/img/w/$weerImageString.png',),
I hope that I can someday helping someone with this. And... if there is an easier way, I would love to hear!
For react, you can use like this:
Step 1: initialize blank state
constructor(){
super()
this.state={
icon:''
}
}
Step 2: api call
async componentDidMount(){
const url = 'http://api.openweathermap.org/data/2.5/'
const key = 'your api key'
const response = await fetch(`${url}weather?q=Guwahati&units=metric&APPID=${key}`)
const data = await response.json() //this will return the json response
const iconName = data.weather[0].icon // this will hold the icon
const iconApi = await fetch('http://openweathermap.org/img/w/' + iconName + '.png')
this.setState({
icon : iconApi.url
})
}
Step 3: Display icon
<div className="weather-icon">
<img style={{width:'70px'}} src= {this.state.icon} />
</div>
Here d refers to day, like n refers to night.
And based on weather status it will change, e.g. 03d for scattered clouds, 01d for clear sky etc.
Here you will get a full list of these icons https://openweathermap.org/weather-conditions#How-to-get-icon-URL
This answer is in reference to the Android,
so after struggling for few hours I finally figured out how to display icons from openweathermap api.
The URL is https://openweathermap.org/img/w/${icon_id}.png
Just put the icon Id you are getting from the API and you will get the result.
Common mistakes which I faced were :
Not using https, as I was using http and it was not working
Also you can get bigger size image by using :
url - https://openweathermap.org/img/wn/${icon_id}#4x.png
icon_id examples : 04d, 10d
working response : https://openweathermap.org/img/wn/04d#4x.png
This is how i solved it. Totally works. no need for JQuery or any of those.
First thing is you realize that the api route is in an array in the weather tab so u have to parse it correctly. use console.log to make sure the get the "10n" kind of result so u know you are getting the right output.
then you use this img tag
<img
alt="icon"
src={http://openweathermap.org/img/w/${icon}.png}
width="120"
height="100"
/>
where icon is the string "04n" that you get from the parsed data.
then it should work perfectly.
Below is my parsed data example. you can see i am geting the temp, humidity, dt_txt is one of the results and icon is the icon
(
{ main: { temp, humidity }, dt_txt, weather: [{ icon }] },
index
)
Firstly, 10d is the icon id that changes according to the forecast data.
I was doing a react weather-App project, and I did the following in my component:
<div>
<img
id="wicon"
src={`http://openweathermap.org/img/wn/${a.weather[0].icon}#2x.png`}
alt="weather icon">
</img>
</div>
This way if the value of the icon change it automatically changes in the Dom.
This worked for me!
create variable to access data between javascript and HTML.
var var1 = document.querySelector('idhere') // you have to use parent class/id
Get icon from JASON
var tempvariable = data['weather'][0]['icon'];
pass link along with html tag to html
var1.innerHTML = "http://openweathermap.org/img/w/" +tempvariable+ ".png' alt='Icon depicting current weather.'>"
or
var1.innerHTML = "http://openweathermap.org/img/w/" +data['weather'][0]['icon']+ ".png' alt='Icon depicting current weather.'>"// step 2 is not required if you use this method.
http://openweathermap.org/img/wn/$weatherData.weather[0].icon#2x.png
To display this on a webpage, you could just add it to the src attribute of an img tag.
This is what the URL for getting the icon will look like....
Where weatherData is the data that you get from the API call you make to the OPENWEATHERMAP. It comes in JSON format. You need to parse.
I think you are asking about IconCode
https://openweathermap.org/
to get converted to an image
For example 02n =>img
So, if thats what you want, then:
You need to use this link
https://openweathermap.org/img/wn/02n#2x.png
Replace the '02n' with the image codes you get as a response
Done
For more image codes information Go to link
const icon = `https://openweathermap.org/img/wn/${weather[0]["icon"]}#2x.png`;
const li = document.createElement("li");
li.classList.add("city");
const markup = `
<figure>
<img class="city-icon" src=${icon} alt=${weather[0]["main"]}>
<figcaption>${weather[0]["description"]}</figcaption>
</figure>
`;
li.innerHTML = markup;
This is what I did and it worked for me. You see, from the response object map through it and with the result access icon as follows
<img src="http://openweathermap.org/img/w/${result.icon}.png" alt="img">
Your html file:
<div class="weather">
<form class="weather-form">
<input type="text" class="city-name">
<input type="submit">
</form>
<img src="" class="iconurl">
</div>
Your JS file:
// hit API
const getWeather = async (cityname) => {
let response = await fetch('https://api.openweathermap.org/data/2.5/weather?q=' + cityname + '&appid=${API KEY}') //you get your api key once you sign up for openweathermap.org
return response.json()
}
// DOM
const weatherContainer = document.querySelector('.weather')
const weatherForm = document.querySelector('.weather-form')
const iconurl = document.querySelector('.iconurl')
// Event Listener
weatherForm.addEventListener('submit', (e) => {
e.preventDefault()
const cityInput = document.querySelector('.city-name')
getWeather(cityInput.value).then(c => {
c.weather.forEach(ww => {
let url = "http://openweathermap.org/img/w/" + ww.icon + ".png"
iconurl.src = url
})
})
})
I had a same problem in Flutter/Dart but not only can't display weather icon but also icon string doesn't have a "http:" in response. I'm working on weatherapi.com.
Here's how You do it in FLUTTER/DART and I'm using Dio package(not http):
In model that You build You need to add:
icon_url = "http:" + json['current']['condition']['icon'] - I did it with "http:" first cause as I said, response doesn't have it in icon url, otherwise just use rest of the code if You're using openweathermap, parameters in [] are just parameters from response, change them, depended on your API. To display icon use Image.network(
nameofyourModel.icon_url). Hope it helps somebody !
ExpressJS:
First Get Icon:
const icon = weather.weather[0].icon;
Second:
iconurl= http://openweathermap.org/img/wn/${icon}.png;
Third:
" alt="">
A little late I must admit. I'm at University right now and I had the same experience as you, where I didn't know how to get the icon to work.
However, a guy at University was kind enough to give me help, which I appreciate very much.
So, in your Javascript, you put:
document.getElementById("icon").src = "https://openweathermap.org/img/wn/" + response.weather[0].icon + "#2x.png";
And in your HTML, you put:
<img id="icon" src = "" alt = "Weather icon">
Hope this helps anyone who was in the same situation as me :)
Thanks!
Related
I am trying to pass data with HTML attribute without using another component to handleClick but I couldn't handle can anyone help me please
const handleLiClickFirst = (airport) => {
setFirst(airport.target.innerHTML);
console.log(airport.target.lat); // I can't read the data here
};
<div className="header__first">
<TextField
id="outlined-basic"
label="From"
variant="outlined"
value={first}
onChange={(e) => setFirst(e.target.value.toLocaleLowerCase())}
/>
<ul>
{resultFirst.airports?.map((airport, i) => {
return (
<li
key={airport.iata}
airport={airport}
onClick={handleLiClickFirst}
lat={airport.latitude}
name={airport.name}
long={airport.longitude}
>
{airport.name} // I can read the data here
</li>
);
})}
</ul>
</div>
Random attributes like airport and lat aren't valid to attach to a native HTML element like <li>. However, you should be able to use data attributes instead to store data on an HTML element.
And you will likely need to use data-airport={JSON.stringify(airport)} instead of just passing the JS object. And if you can avoid passing the entire object in, (by saving each of the properties that you need separately, like you are already doing with latitude, for example) that may be best to avoid to prevent creating massive HTML attribute strings.
I solve this problem without attributes and the handleClick Method after I couldn't reach the data. I removed handleClick from onClick and added the code in onClick
onClick={() => {
setFirst(airport.name);
// setFirstLatlong([airport.latitude,airport.longitude]);
setFirstLatlong({
lat: airport.latitude,
long: airport.longitude,
});
}}
#Jacob K I will try to use your method on an upcoming project. Thank you
I want to create a React webpage that has both editable and read-only versions, the whole page not just a few elements on the page. A version is displayed to the user based on user id and other conditions. How do I do it?
The only straight forward way I know is to create 2 pages one editable and one read-only and based on the condition show the appropriate version (html page) to the user.
Is there a better and smarter way to do this? Like can I create just one page for both versions and toggle the mode based on the condition to the users?
Your question should have provided an example of some code you had tried but based on the description, very rough example below of one of many possible solutions.
Suppose EditView component is your page and you are able to pass a value for permission based on whatever credential you need to apply.
Then you have a component, ExampleField that takes the permission and displays either an input or static text. A collection of multiple of these fields is mapped from a theoretical array of data that you'll have to fetch from somewhere and the fields are returned by the main component.
const EditView = ({permission}) => {
const [editable, setEditable] = useState();
const [values, setValues] = useState([]);
useEffect(() => {
setEditable(permission);
}, [permission]);
useEffect(() => {
//maybe fetch your data from a back end or whatever and assign it to `values`
//on page load
}, [])
const ExampleField = ({permission, val, index}) => {
const handleChange = (e) => {
let vals = [...values];
vals[index] = val;
setValues(vals);
}
return(
<>
{permission
? <input name="example" type="text" defaultValue={val}
onChange={handleChange} />
: <span>{val}</span>}
</>
)
}
const fields = values.map((value, i) => {
return <ExampleField permission={permission} val={value} index={i}/>
})
return(
<>
{fields}
</>
)
}
Most likely, you'll want to break out various field components into their own file and, instead of using useState, you would probably want to explore useContext or useStore type functionality to lift up your state and do all the react things.
*Haven't tested or even compiled this code - for illustration purposes only.
this is my first post here. I am building a React Boostrap Carousel that pulls Movie data from the database and displays it. I am new to React and programming in general. So far i made the code work. But i do not know how to handle the images. The images are stores in React **src/assets/imgs. **. Should i store a reference to the image in the database like so ../../assets/imgs/the-batman.jpg and then display it? If so later on on the project the admin will have to create a MovieOfTheMonth. He should be able to input movie title, descrition etc, and also upload a movie image. Is there a way when the image is uploaded it, to store it to a specific folder, in this case src/assets/imgs and also create a reference in the database? I do not need the solution here, just to tell me if it is achievable. Finally is there a way to improve my code?
this is my full code for this component
import React, {useState, useEffect } from 'react';
import './Carousel.css'
import Carousel from 'react-bootstrap/Carousel';
import 'bootstrap/dist/css/bootstrap.min.css';
import axios from 'axios';
const CarouselHero = () => {
//boostrap code
const [index, setIndex] = useState(0);
const handleSelect = (selectedIndex, e) => {
setIndex(selectedIndex);
};
//Get Movies of the month
const [movie, setMovie] = useState([])
const getMovie = () => {
axios.get("http://localhost:4000/moviesOfTheMonth")
.then((res) => {
const myMovie = res.data
myMovie.push()
setMovie(myMovie);
})
}
useEffect(() => getMovie(), []);
return (
<Carousel activeIndex={index} onSelect={handleSelect} fade>
{movie.map((item) => {
const {id, title, description} = item.Movie
return (
<Carousel.Item interval={2000}>
<img
src={require("../../assets/imgs/the-batman.jpg")}
alt="First slide"
/>
<Carousel.Caption >
<h1>{title}</h1>
<p>{description}</p>
<button>Book Now</button>
</Carousel.Caption>
</Carousel.Item>
)
})}
</Carousel>
);
};
export default CarouselHero;
I think technically it is achievable to iterate over the assets folder and create database entries for new images (create and compare hash?), but it is usually not how you do it. I would put images in some file storage like S3 and reference them with id.
I don't know who the admin will be in your project, but if admin is rather a non technical person, you could create (or use a template of course) a small and simple admin dashboard, where he/she can maintain a movie of the month via UI.
FFinally some remarks on your code:
const handleSelect = (selectedIndex, e) => { setIndex(selectedIndex); }; - If you need only first, but not second, third etc. argument, you can just leave it out: (selectedIndex) => ...
const [movie, setMovie] = useState([]) - don't forget to use semicolon after every statement. (They are optional, but are useful sometimes to avoid weird errors). Also, you have a list here. So maybe better call it "movies".
myMovie.push() - What are you trying to push here?
useEffect(() => getMovie(), []); - Usually you define and call async function directly in useEffect. Don't you get any hints or warning?
movie.map((item) => { - When you iterate and get a list back React needs a key on every element (here on Carousel.Item). Don't just use the index, as it is a bad practice. Always try to find id property in your data.
const {id, title, description} = item.Movie - Why is the data nested by Movie object? Can't you just say item.id, item.title, item.description?
I developed project using anguler with ngRx framework. I used TypeScript with HTML for developing front-end.My db have saved 'HTML' format texts like below.
"<html><body>A.txt
B.txt
D.txt
www.facebook.com
</body></html>"
This text priviouly , I drectly render in html file using <dev INNERHTML ={{stringText }} \> like wise.
But my project using JXBrowser and as it's configuration , this can't be directly open in default browser clicking just link.
For that work ,I need to take href location as URL and when click it passed to .ts file.
I thought ,it change as like this <a role="button" click='getLink(myText)'> {{getLink(value}} </a>'. so ,create this ,I need that text put a array with contain 'location' and value.Next ,I though ,Iterate that array in HTML file.
I need some expert help to do this ? I am struggle with map above text to such kind of string array (eg :array[hrfeLink][value]). Hope some expert help me.
------------Updated---------------
According to the comment, I will try this way, and I can take the link location. But still couldn't take value.
let parser = new DOMParser();
let doc = parser.parseFromString(info, "text/html");
let x = doc.getElementsByTagName('a');
for (let i = 0; i < x.length ; i++) {
console.log(x[i].getAttribute('href'));
}
What is the value that you want? Is it the anchor text of the link?
We create an interface Link with the properties that we want from each link
interface Link {
location: string;
value: string;
}
Then we create a function that extracts all links from an html string and converts them to an array of Link objects.
function parseLinks( stringHTML: string ): Link[] {
// create a parser object
const parser = new DOMParser();
// turn the string into a Document
const doc = parser.parseFromString( stringHTML, "text/html" );
// get all links
const linkNodes = doc.getElementsByTagName('a');
// convert from HTMLCollection to array to use .map()
const linksArray = [...linkNodes];
// map from HTMLAnchorElement to Link object
return linksArray.map( element => ({
location: element.href,
value: element.innerText,
}))
}
Now you can do whatever with the links from your text
const text = `<html><body>A.txt
B.txt
D.txt
www.facebook.com
</body></html>`;
const links: Link[] = parseLinks( text );
// can use like this
links.map( ({location, value}) => {
// do something here
})
Typescript Playground Link
I have a very long document - 40000 words - I would like to display in a styled manner, like html.
I need to display it with headers, paragraphs and bold styling.
I am building an Angular app. I tried loading the converted document as a local html, but it takes a very long time.
For instance, I tried this:
var html = this.http.get("../data.html").map(ref => {
console.log(html);
} );
Are there any other ways I can load this text? Maybe break it up into smaller chunks somehow?
Based on what you've provided with no other context:
You need to subscribe to the Observable otherwise, nothing will ever happen since Observable execution is lazy:
var html = this.http.get("../data.html")
.map(ref => {
console.log(html);
return ref;
})
.subscribe(ref => ...);
Also, you're using console.log(html) in your map, but html does not exist in the context of map so you would need to do something like:
var html = this.http.get("../data.html")
.map(ref => {
console.log(ref); // Does this log appear and what does it contain?
return ref;
})
.subscribe(ref => ...);
Finally, var html is an Observable not HTML so I'd probably rename this to something a bit more descriptive if you're passing it around and subscribing to the response:
const data$ = this.http.get("../data.html")
.map(ref => {
console.log(ref);
return ref;
});
// ... do other stuff
data$.subscribe(ref => ...);
Or if not passed chain it and subscribe which indicates the Observeable has completed:
this.http.get("../data.html")
.map(ref => {
console.log(ref);
return ref;
}).subscribe(ref => ...);
If this doesn't help answer the question it's because you haven't provided enough information, and I'd suggest answering:
In the second example what does console.log(ref) output?
Include more code that provides more context like do you use subscribe already and what does the data you're using look like?
Make an example in StackBlitz that replicates the issue. Just click Angular and you get a pre-made Angular application you can drop your code into and then people can hack directly on the issue. Takes tops 5 seconds to setup