Popular Searches
Popular Course Categories
Popular Courses

Developing a Weather Application Using a REST API

Developing a Weather Application Using a REST API

React Native Practical Projects, Portfolio, and Interview Preparation

Developing a Weather Application Using a REST API

Course: React Native Training

Topic: Developing a Weather Application Using a REST API

Course Link: React Native Training

Demo Link: Register for a Course Demo

JustAcademy Website: Visit JustAcademy


1. Introduction to Weather Application Development

A weather application is a mobile application that displays weather information such as temperature, humidity, wind speed, atmospheric pressure, and weather conditions for a particular location. React Native allows developers to create weather applications for Android and iOS using JavaScript or TypeScript and reusable components.

Weather conditions change continuously, so an application needs to retrieve updated information from a weather service. A REST API makes this possible by allowing the application to send HTTP requests to a remote server and receive structured data in response.

For example, when a user searches for Mumbai, the application sends a request to a weather API. The server processes the request and returns information about Mumbai's weather. The application then displays the returned information using React Native components.

1.1 Main Features of the Application

  • Search for weather information by city name.
  • Retrieve current weather conditions from a REST API.
  • Display temperature in Celsius or Fahrenheit.
  • Show humidity, wind speed, and weather descriptions.
  • Display a loading indicator while data is being retrieved.
  • Handle invalid city names and network errors.
  • Refresh weather information when required.
  • Provide a responsive and user-friendly interface.

1.2 Learning Objectives

After completing this topic, learners will be able to:

  • Understand REST APIs and HTTP communication.
  • Configure a weather API provider and obtain an API key.
  • Send GET requests from a React Native application.
  • Use Fetch, async, and await for asynchronous operations.
  • Understand JSON responses and access nested properties.
  • Manage weather data using React hooks.
  • Build reusable user interface components.
  • Implement loading, success, and error states.
  • Test API integration and troubleshoot common errors.
  • Apply security and performance best practices.

2. Understanding REST APIs

2.1 What Is an API?

API stands for Application Programming Interface. It defines how one software application communicates with another system through a specified interface.

In a weather application, React Native manages the user interface while the weather service provides weather information. The API acts as the communication interface between these systems.

For example, the application requests the current temperature and humidity of a city. The weather server processes the request and returns the required information.

2.2 What Is a REST API?

REST stands for Representational State Transfer. A REST API commonly exposes resources through URLs and uses HTTP methods to retrieve or modify information.

HTTP Method Purpose Example
GET Retrieve information. Get the current weather for Mumbai.
POST Submit information to a server. Submit feedback to a backend service.
PUT Replace a resource. Replace a saved user preference.
PATCH Partially update a resource. Update one preference.
DELETE Delete a resource. Remove a saved location from a backend.

A basic weather application mainly uses GET requests because its primary task is to retrieve weather information rather than modify the provider's data.

2.3 How a Weather API Works

  1. The user enters a city name.
  2. The application validates the input.
  3. The application creates the API request URL.
  4. The Fetch API sends an HTTP GET request.
  5. The weather server processes the request.
  6. The server returns an HTTP response containing weather data.
  7. The application checks the response status.
  8. The response body is parsed into JSON.
  9. The application stores the data in React state.
  10. The interface updates to display the weather information.

2.4 Weather Application Request Flow

User enters a city
        |
        v
React Native interface
        |
        v
Validate city input
        |
        v
Create API request URL
        |
        v
Send HTTP GET request
        |
        v
Weather API server
        |
        v
Receive JSON response
        |
        v
Validate and process data
        |
        v
Update React state
        |
        v
Display weather information

3. Setting Up the Development Environment

3.1 Prerequisites

Before starting the project, learners should understand basic JavaScript, React components, React Native styling, asynchronous functions, and JSON objects.

3.2 Required Tools

Tool Purpose
Node.js Provides the JavaScript runtime and development tools.
npm Installs dependencies and executes project scripts.
Expo Simplifies React Native project setup and testing.
Visual Studio Code Provides an editor for writing application code.
Android emulator or physical device Runs and tests the mobile application.
Weather API provider Supplies weather information through HTTP requests.

3.3 Creating a React Native Project

Run the following commands in a terminal to create an Expo-based React Native project.

npx create-expo-app@latest WeatherApp
cd WeatherApp
npx expo start

Open the generated project in your code editor. Depending on the selected template, the main screen may be defined in App.js, App.tsx, or a route file inside an app directory.

4. Selecting and Configuring a Weather API

A weather API provides the current conditions and forecasts that the application displays. Select a provider based on its supported endpoints, data coverage, request limits, pricing, and terms of use.

4.1 Example Weather API Provider

This tutorial uses OpenWeather as an example provider.

Website: OpenWeather

Current weather documentation: Current Weather Data API

4.2 Obtaining an API Key

  1. Visit the weather provider's official website.
  2. Create an account or sign in.
  3. Open the API key or account dashboard section.
  4. Create or copy an API key according to the provider's instructions.
  5. Review the endpoint documentation and required parameters.
  6. Check whether the key is active and permitted to access the selected endpoint.
  7. Test the request using a development environment.

An API key identifies or authorizes a client when it requests data. An incorrect, inactive, or unauthorized key may cause an authentication error.

4.3 Understanding the API Endpoint

An endpoint is the URL through which an application accesses a particular API resource.

https://api.openweathermap.org/data/2.5/weather

The current weather endpoint accepts query parameters such as the city name, units, and API key.

https://api.openweathermap.org/data/2.5/weather?q=Mumbai&units=metric&appid=YOUR_API_KEY
Parameter Description
q Specifies the city to search for.
units=metric Requests metric units, including Celsius for temperature.
appid Provides the API key required by this endpoint.

Replace YOUR_API_KEY with your own configured key. Do not publish a real key in public repositories, screenshots, or production source code.

5. Understanding JSON Weather Responses

JSON stands for JavaScript Object Notation. It is a structured text format used to exchange data between applications and servers.

5.1 Example JSON Response

The following response is illustrative. Actual weather values depend on the requested location and the information returned by the provider.

{
  "name": "Mumbai",
  "main": {
    "temp": 29.5,
    "feels_like": 33.2,
    "humidity": 75,
    "pressure": 1008
  },
  "weather": [
    {
      "main": "Clouds",
      "description": "scattered clouds"
    }
  ],
  "wind": {
    "speed": 4.1
  }
}

5.2 Important JSON Properties

Property Purpose Example
name Location name. Mumbai
main.temp Current temperature. 29.5
main.feels_like Perceived temperature. 33.2
main.humidity Relative humidity percentage. 75
main.pressure Atmospheric pressure. 1008 hPa
weather[0].main Short weather category. Clouds
weather[0].description Detailed weather description. Scattered clouds
wind.speed Wind speed in the requested unit system. 4.1 m/s

5.3 Accessing Nested Properties

JavaScript dot notation accesses properties inside nested objects, while array indexing accesses elements in arrays.

const temperature = data.main.temp;
const humidity = data.main.humidity;
const city = data.name;
const description = data.weather[0].description;
const windSpeed = data.wind.speed;

Check that expected properties exist before accessing them. Error responses may have a different structure from successful weather responses.

6. Making API Requests with Fetch

The Fetch API allows React Native applications to send HTTP requests. It returns a Promise that resolves to a Response object when the server responds.

6.1 Basic GET Request

async function getWeather() {
  const url =
    "https://api.openweathermap.org/data/2.5/weather" +
    "?q=Mumbai&units=metric&appid=YOUR_API_KEY";

  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(
      `Weather request failed: ${response.status}`
    );
  }

  const data = await response.json();
  return data;
}

6.2 Understanding async and await

  • async: Declares a function that returns a Promise.
  • await: Waits for an asynchronous operation to settle before continuing inside the async function.
  • fetch(): Sends the HTTP request.
  • response.ok: Indicates whether the HTTP status is in the successful range.
  • response.json(): Reads and parses the response body as JSON.
  • try/catch: Handles errors during request processing.

6.3 Why Check response.ok?

Fetch does not automatically throw an exception for every unsuccessful HTTP status. A response with a status such as 401, 404, or 500 may still resolve to a Response object.

const response = await fetch(url);

if (!response.ok) {
  throw new Error(`HTTP error: ${response.status}`);
}

const data = await response.json();

Checking the status before parsing the successful response helps the application distinguish server errors from valid weather data.

7. Designing the Weather Application Interface

A weather application should display essential information clearly and make searching for a location simple.

7.1 Recommended UI Components

  • SafeAreaView: Helps keep content within the safe screen area.
  • Text: Displays headings, temperatures, and descriptions.
  • TextInput: Accepts the city name.
  • Pressable: Provides interactive search and refresh controls.
  • ActivityIndicator: Displays loading feedback.
  • View: Groups and arranges interface elements.
  • ScrollView: Allows content to scroll on smaller screens.

7.2 Example Interface Layout

----------------------------------
          WEATHER APP
----------------------------------
Enter City: [ Mumbai           ]
             [ Get Weather ]

               Mumbai
                 30°C
            Scattered Clouds

          Feels Like: 33°C
          Humidity: 75%
          Wind Speed: 4.1 m/s

            [ Refresh Weather ]
----------------------------------

The displayed values are examples only. The running application should show the actual values returned by the weather service.

8. Managing State with useState

The useState hook stores information that can change while the application is running. In a weather application, state is needed for the city input, API response, loading indicator, and error message.

8.1 Defining State Variables

import React, { useState } from "react";

const [city, setCity] = useState("");
const [weather, setWeather] = useState(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");

These declarations must be placed inside a React function component or a custom hook.

State Initial Value Purpose
city Empty string Stores the search input.
weather null Stores the successful API response.
loading false Indicates whether a request is in progress.
error Empty string Stores an error message.

8.2 Updating State

setCity("Mumbai");
setWeather(data);
setLoading(false);
setError("");

Use the setter functions to update state. Avoid mutating the existing weather response object directly.

9. Building the Weather Application

The following example demonstrates city search, API integration, JSON parsing, loading feedback, and error handling. It is intended as a learning implementation for a single weather screen.

Security note: The example uses a placeholder API key. A real API key embedded in a mobile application can potentially be extracted. For production, use a backend service to protect secret credentials when required by the API provider.

9.1 Example App.js

import React, { useState } from "react";
import {
  View,
  Text,
  TextInput,
  Pressable,
  ActivityIndicator,
  ScrollView,
  StyleSheet,
  SafeAreaView
} from "react-native";

const API_KEY = "YOUR_API_KEY";
const API_URL =
  "https://api.openweathermap.org/data/2.5/weather";

export default function App() {
  const [city, setCity] = useState("");
  const [searchedCity, setSearchedCity] = useState("");
  const [weather, setWeather] = useState(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");

  async function fetchWeather(cityName = city) {
    const trimmedCity = cityName.trim();

    if (!trimmedCity) {
      setWeather(null);
      setError("Please enter a city name.");
      return;
    }

    if (API_KEY === "YOUR_API_KEY") {
      setError("Configure a valid weather API key.");
      return;
    }

    setLoading(true);
    setError("");

    try {
      const url =
        `${API_URL}?q=${encodeURIComponent(trimmedCity)}` +
        `&units=metric&appid=${encodeURIComponent(API_KEY)}`;

      const response = await fetch(url);

      if (!response.ok) {
        if (response.status === 404) {
          throw new Error("City not found. Check the spelling.");
        }

        if (response.status === 401) {
          throw new Error("Invalid or inactive API key.");
        }

        if (response.status === 429) {
          throw new Error("API request limit reached.");
        }

        throw new Error(
          `Weather request failed: ${response.status}`
        );
      }

      const data = await response.json();

      if (
        !data.main ||
        !Array.isArray(data.weather) ||
        !data.weather[0]
      ) {
        throw new Error("Unexpected weather response.");
      }

      setWeather(data);
      setSearchedCity(data.name || trimmedCity);
    } catch (err) {
      setWeather(null);
      setError(
        err instanceof Error
          ? err.message
          : "Unable to retrieve weather information."
      );
    } finally {
      setLoading(false);
    }
  }

  return (
    <SafeAreaView style={styles.safeArea}>
      <ScrollView contentContainerStyle={styles.container}>
        <Text style={styles.title}>Weather App</Text>

        <Text style={styles.subtitle}>
          Check current weather by city
        </Text>

        <TextInput
          style={styles.input}
          placeholder="Enter city name"
          value={city}
          onChangeText={setCity}
          onSubmitEditing={() => fetchWeather()}
          returnKeyType="search"
          autoCapitalize="words"
          accessibilityLabel="City name"
        />

        <Pressable
          style={[
            styles.button,
            loading && styles.buttonDisabled
          ]}
          onPress={() => fetchWeather()}
          disabled={loading}
          accessibilityRole="button"
        >
          <Text style={styles.buttonText}>
            {loading ? "Loading..." : "Get Weather"}
          </Text>
        </Pressable>

        {loading && (
          <ActivityIndicator
            size="large"
            style={styles.loader}
            accessibilityLabel="Loading weather"
          />
        )}

        {!!error && (
          <Text style={styles.error}>{error}</Text>
        )}

        {weather && !loading && (
          <View style={styles.card}>
            <Text style={styles.city}>
              {searchedCity}
            </Text>

            <Text style={styles.temperature}>
              {Math.round(weather.main.temp)}°C
            </Text>

            <Text style={styles.description}>
              {weather.weather[0].description}
            </Text>

            <View style={styles.details}>
              <Text style={styles.detailText}>
                Feels Like: {Math.round(weather.main.feels_like)}°C
              </Text>

              <Text style={styles.detailText}>
                Humidity: {weather.main.humidity}%
              </Text>

              {typeof weather.wind?.speed === "number" && (
                <Text style={styles.detailText}>
                  Wind Speed: {weather.wind.speed} m/s
                </Text>
              )}

              {typeof weather.main.pressure === "number" && (
                <Text style={styles.detailText}>
                  Pressure: {weather.main.pressure} hPa
                </Text>
              )}
            </View>

            <Pressable
              style={styles.refreshButton}
              onPress={() => fetchWeather(searchedCity)}
              disabled={loading}
              accessibilityRole="button"
            >
              <Text style={styles.refreshText}>
                Refresh Weather
              </Text>
            </Pressable>
          </View>
        )}

        <Text style={styles.footer}>
          Weather information is provided by a remote API.
        </Text>
      </ScrollView>
    </SafeAreaView>
  );
}

const styles = StyleSheet.create({
  safeArea: {
    flex: 1,
    backgroundColor: "#F0F7FF"
  },
  container: {
    flexGrow: 1,
    justifyContent: "center",
    padding: 24
  },
  title: {
    fontSize: 30,
    fontWeight: "bold",
    textAlign: "center",
    color: "#153E75"
  },
  subtitle: {
    fontSize: 15,
    textAlign: "center",
    color: "#526579",
    marginTop: 8,
    marginBottom: 24
  },
  input: {
    backgroundColor: "#FFFFFF",
    borderWidth: 1,
    borderColor: "#CBD5E1",
    borderRadius: 10,
    padding: 14,
    fontSize: 16,
    marginBottom: 12
  },
  button: {
    backgroundColor: "#2563EB",
    padding: 15,
    borderRadius: 10,
    alignItems: "center"
  },
  buttonDisabled: {
    opacity: 0.6
  },
  buttonText: {
    color: "#FFFFFF",
    fontSize: 16,
    fontWeight: "bold"
  },
  loader: {
    marginTop: 20
  },
  error: {
    color: "#B91C1C",
    backgroundColor: "#FEE2E2",
    padding: 12,
    borderRadius: 8,
    marginTop: 18
  },
  card: {
    backgroundColor: "#FFFFFF",
    borderRadius: 16,
    padding: 22,
    marginTop: 24,
    alignItems: "center",
    elevation: 3
  },
  city: {
    fontSize: 25,
    fontWeight: "bold",
    color: "#153E75"
  },
  temperature: {
    fontSize: 52,
    fontWeight: "300",
    color: "#2563EB",
    marginTop: 10
  },
  description: {
    fontSize: 18,
    textTransform: "capitalize",
    color: "#526579",
    marginTop: 4
  },
  details: {
    alignSelf: "stretch",
    marginTop: 22,
    gap: 12
  },
  detailText: {
    fontSize: 16,
    color: "#334155"
  },
  refreshButton: {
    marginTop: 22,
    padding: 12,
    borderRadius: 8,
    backgroundColor: "#DBEAFE",
    alignSelf: "stretch",
    alignItems: "center"
  },
  refreshText: {
    color: "#1D4ED8",
    fontWeight: "bold"
  },
  footer: {
    textAlign: "center",
    color: "#64748B",
    fontSize: 12,
    marginTop: 24
  }
});

Code formatting note: The JSX tags and arrow operators in this HTML notes block are escaped for display. When transferring the example into App.js, convert them to normal JSX syntax. For example, replace &lt;SafeAreaView&gt; with the actual SafeAreaView opening tag and use the normal => arrow operator. The JavaScript URL template uses ordinary ampersands in the source code.

9.2 Explanation of the Application

  1. State initialization: Stores the input city, retrieved weather, loading status, and error message.
  2. Input validation: Prevents a blank city search.
  3. URL creation: Uses encodeURIComponent to safely encode the city name.
  4. Loading feedback: Activates the loading indicator before the request starts.
  5. API communication: Sends a GET request to the weather endpoint.
  6. Status checking: Handles common unsuccessful HTTP responses.
  7. JSON parsing: Converts the successful response into a JavaScript object.
  8. State update: Stores the returned weather information.
  9. Error handling: Displays an error when a request fails.
  10. Cleanup: Resets the loading state inside finally.

9.3 Why Use encodeURIComponent?

City names may contain spaces or special characters. Encoding the value helps create a valid query parameter.

const city = "New Delhi";
const encodedCity = encodeURIComponent(city);

console.log(encodedCity);

Always encode dynamic query values instead of inserting user input directly into a URL.

10. Handling Loading, Success, and Error States

A reliable application must communicate whether it is loading information, has successfully retrieved data, or has encountered a problem.

10.1 Loading State

{loading && (
  <ActivityIndicator size="large" />
)}

The loading indicator provides immediate feedback while the application waits for a response.

10.2 Success State

{weather && (
  <Text>
    Temperature: {Math.round(weather.main.temp)}°C
  </Text>
)}

The weather card should render only when valid weather data is available.

10.3 Error State

{error ? (
  <Text>{error}</Text>
) : null}

Display a readable error message instead of leaving users with an unexplained blank screen.

10.4 Common HTTP Errors

Status or Error Possible Cause Recommended Action
400 Bad Request Malformed or missing parameters. Verify the endpoint and query parameters.
401 Unauthorized Invalid or inactive credentials. Check the API key and account configuration.
404 Not Found The requested city is not found. Check the spelling and location query.
429 Too Many Requests The request limit has been exceeded. Reduce unnecessary calls and follow provider retry guidance.
5xx Server Error The remote service encountered a problem. Display a temporary error and retry later.
Network error Connectivity or connection failure. Check internet access and retry.
JSON parsing error Unexpected or invalid response body. Inspect the response format and content.

11. Using useEffect for Automatic Weather Requests

The useEffect hook runs side effects in a functional component. It can retrieve weather information when a selected city changes.

11.1 Basic useEffect Structure

import React, { useEffect, useState } from "react";

function WeatherExample() {
  const [city, setCity] = useState("Mumbai");
  const [weather, setWeather] = useState(null);

  useEffect(() => {
    // Retrieve weather when the selected city changes.
  }, [city]);

  return null;
}

This example illustrates the hook structure. A complete implementation must include the request logic, error handling, and appropriate handling of stale requests.

11.2 Preventing Stale Responses

If a user searches for two cities quickly, an earlier request may finish after a newer request. Without protection, the earlier response might overwrite the latest result.

useEffect(() => {
  let active = true;

  async function loadWeather() {
    try {
      const response = await fetch(url);

      if (!response.ok) {
        throw new Error("Weather request failed.");
      }

      const data = await response.json();

      if (active) {
        setWeather(data);
        setError("");
      }
    } catch (err) {
      if (active) {
        setWeather(null);
        setError("Unable to load weather.");
      }
    }
  }

  loadWeather();

  return () => {
    active = false;
  };
}, [url]);

This is a pattern rather than a complete standalone component. Define url and the state setters in the surrounding component. The active flag prevents stale state updates but does not cancel the network request itself. An AbortController can be used when supported by the runtime and request setup.

12. Displaying Weather Icons and Conditions

Weather icons improve readability by helping users recognize conditions quickly.

12.1 Displaying the Weather Description

const description =
  weather?.weather?.[0]?.description ?? "Weather unavailable";

Optional chaining helps prevent errors when a nested property is missing. The nullish coalescing operator supplies a fallback value when the expression is null or undefined.

12.2 Mapping Conditions to Symbols

function getWeatherSymbol(condition) {
  const value = condition?.toLowerCase();

  if (value === "clear") return "☀️";
  if (value === "clouds") return "☁️";
  if (value === "rain") return "🌧️";
  if (value === "thunderstorm") return "⛈️";
  if (value === "snow") return "❄️";
  if (value === "mist" || value === "fog") return "🌫️";

  return "🌤️";
}

Adjust the mapping to match the weather categories returned by the selected provider.

13. Adding Forecast Information

A weather application can be extended to display predicted conditions for future hours or days. Forecast data may include temperature, precipitation probability, wind conditions, and weather descriptions.

13.1 Current Weather vs. Forecast

Feature Current Weather Forecast
Purpose Displays current observed conditions. Displays predicted future conditions.
Typical fields Temperature, humidity, wind, description. Forecast temperature, precipitation, wind, condition.
Endpoint Current weather endpoint. Forecast endpoint supported by the provider.
Interface Current-weather card. Forecast list or horizontal cards.

13.2 Rendering Forecast Items

import React from "react";
import { FlatList, Text, View } from "react-native";

function ForecastList({ items }) {
  return (
    <FlatList
      data={items}
      keyExtractor={(item, index) =>
        String(item.dt ?? index)
      }
      renderItem={({ item }) => (
        <View>
          <Text>{item.dt_txt ?? "Forecast"}</Text>
          <Text>
            {item.main?.temp != null
              ? `${Math.round(item.main.temp)}°C`
              : "Temperature unavailable"}
          </Text>
          <Text>
            {item.weather?.[0]?.description ??
              "Condition unavailable"}
          </Text>
        </View>
      )}
    />
  );
}

export default ForecastList;

This component illustrates rendering forecast data. Connect it to a supported forecast endpoint and adjust the response mapping to the provider's documented schema.

14. Retrieving Weather by Device Location

Another useful feature is automatically retrieving weather for the user's current location. This requires location permissions and a weather endpoint that accepts geographic coordinates.

14.1 Location-Based Workflow

  1. Explain why location access is useful.
  2. Request the required device permission.
  3. Retrieve latitude and longitude using a suitable location library.
  4. Handle permission denial and unavailable location data.
  5. Send the coordinates to the weather API.
  6. Display the returned weather information.

14.2 Example Coordinate-Based URL

const url =
  `${API_URL}?lat=${latitude}` +
  `&lon=${longitude}` +
  `&units=metric&appid=${API_KEY}`;

This example shows the request structure. Define the coordinates from a valid location result and confirm that the endpoint supports these parameters.

For Expo applications, refer to the Expo Location documentation.

14.3 Location Permission Best Practices

  • Request permission only when the feature requires it.
  • Explain the purpose of location access.
  • Provide manual city search as an alternative.
  • Handle timeouts and unavailable GPS data.
  • Collect only the location information required for the feature.
  • Follow applicable privacy and platform requirements.

15. API Key Security

API credentials must be handled carefully. Mobile application packages can be inspected, so a key embedded in the JavaScript bundle should not be considered confidential.

15.1 Security Best Practices

  • Never commit real API keys to public repositories.
  • Use a protected backend for secret credentials where required.
  • Keep development and production credentials separate.
  • Apply provider-supported restrictions and usage limits.
  • Monitor unexpected requests and usage.
  • Avoid logging credentials or sensitive user information.
  • Validate inputs before making API calls.
  • Use HTTPS for API communication.
  • Follow the provider's terms for client-side key usage.

15.2 Environment Variables

Environment variables help manage configuration, but values embedded into a client-side mobile bundle can still be extracted. They do not automatically protect secret API keys.

const WEATHER_API_BASE_URL =
  "https://api.openweathermap.org/data/2.5/weather";

For a production architecture, the app can call a backend service. The backend can protect the provider's secret credentials, validate requests, and apply rate limits.

16. Testing the Weather Application

Testing verifies that the application works correctly with valid responses and handles unsuccessful requests without crashing.

16.1 Manual Testing Checklist

  • Search for a valid city.
  • Search for a city name containing spaces.
  • Submit an empty input field.
  • Search for an unknown city.
  • Verify that the loading indicator appears during requests.
  • Check that temperature uses the selected units.
  • Verify humidity and wind speed against the returned data.
  • Test when the device is offline.
  • Test with an invalid API key.
  • Test the response to rate limits and server failures.
  • Refresh the weather information.
  • Test repeated searches for different cities.
  • Verify the interface on different screen sizes.
  • Check keyboard interaction and accessibility labels.

16.2 Example Test Cases

Test Case Input or Condition Expected Result
Valid city Mumbai Weather information appears if the request succeeds.
Empty search Blank input Validation message appears without an API request.
Unknown city Invalid city name A useful error message appears.
Invalid API key Incorrect credentials An authentication error is displayed.
Network failure Device offline The application displays a network error.
Repeated search Two different cities The latest successful result is displayed.
Refresh Tap the refresh button A new request is made for the selected location.

17. Troubleshooting Common Problems

17.1 Weather Data Is Not Displayed

Possible causes: Incorrect endpoint, invalid API key, unsuccessful HTTP status, or incorrect property access.

  • Inspect the HTTP response status.
  • Verify the endpoint and query parameters.
  • Check the JSON response structure.
  • Confirm that state is updated after successful parsing.
  • Check the conditions used to render the weather card.

17.2 Temperature Is Undefined

Ensure that the code accesses the correct nested property.

// Incorrect for the example response:
const temperature = data.temp;

// Correct for the example current-weather response:
const temperature = data.main.temp;

17.3 City Names with Spaces Fail

Encode the city name before adding it to the query string.

const city = "New Delhi";

const url =
  `${API_URL}?q=${encodeURIComponent(city)}` +
  `&units=metric&appid=${API_KEY}`;

17.4 Loading Indicator Does Not Disappear

Make sure loading is reset whether the request succeeds or fails.

try {
  // Perform the API request.
} catch (error) {
  // Handle the error.
} finally {
  setLoading(false);
}

17.5 API Key Error

Check the API key, account configuration, endpoint permissions, and provider activation requirements.

17.6 Network Request Fails

  • Verify that the device has internet access.
  • Confirm that the endpoint uses HTTPS.
  • Inspect the response status and error message.
  • Check whether the service is available.
  • Confirm that the API usage limit has not been exceeded.

18. Performance Optimization

Performance optimization helps the application remain responsive and avoids unnecessary API traffic.

18.1 Avoid Unnecessary Requests

Trigger requests when the user submits a city, selects a location, or refreshes the result. Avoid sending a request for every keystroke in the search field.

18.2 Debounce Search Suggestions

For automatic search suggestions, debounce input so that the application waits briefly after typing stops before making a request. This can reduce unnecessary API calls.

18.3 Cache Weather Results

Caching can improve responsiveness and support limited offline access. Store the retrieval time and clearly label cached results so that users do not mistake old information for current conditions.

18.4 Prevent Stale Data

Weather conditions change frequently. Show a last-updated timestamp where appropriate and refresh data according to the application's requirements and the provider's usage limits.

18.5 Separate API Logic from UI Components

Moving API logic into a service module makes the code easier to test, reuse, and maintain.

// services/weatherService.js

const BASE_URL =
  "https://api.openweathermap.org/data/2.5/weather";

export async function getCurrentWeather(city, apiKey) {
  const url =
    `${BASE_URL}?q=${encodeURIComponent(city)}` +
    `&units=metric&appid=${encodeURIComponent(apiKey)}`;

  const response = await fetch(url);

  if (!response.ok) {
    throw new Error(
      `Weather request failed: ${response.status}`
    );
  }

  return response.json();
}

This example accepts an API key as a parameter for demonstration. For production use, protect secret credentials on a backend when required.

19. Recommended Project Structure

A logical folder structure helps separate user interface components, API services, and helper functions.

WeatherApp/
├── App.js
├── components/
│   ├── WeatherCard.js
│   ├── SearchBar.js
│   ├── LoadingView.js
│   └── ErrorMessage.js
├── screens/
│   └── WeatherScreen.js
├── services/
│   └── weatherService.js
├── utils/
│   └── weatherHelpers.js
└── assets/
    └── icons/

The exact structure depends on the project template. An Expo Router project may use route files inside an app directory instead of a single App.js screen.

20. Mini Project: Weather Application

Build a complete weather application that retrieves current weather information for a city entered by the user.

20.1 Project Requirements

  • Create a React Native user interface.
  • Allow users to enter a city name.
  • Connect to a weather REST API.
  • Display temperature, weather description, humidity, and wind speed.
  • Show loading feedback during requests.
  • Display helpful errors for invalid input and unsuccessful requests.
  • Add a refresh feature.
  • Organize the application into reusable components.
  • Keep API request logic separate where appropriate.
  • Test the application on an emulator or physical device.

20.2 Advanced Features

  • Location-based weather.
  • Hourly and multi-day forecasts.
  • Favorite cities.
  • Celsius and Fahrenheit selection.
  • Weather icons and condition-based themes.
  • Search suggestions and recent locations.
  • Offline display of labelled cached data.
  • Pull-to-refresh interaction.
  • Automated tests for API requests and interface states.

20.3 Project Evaluation Criteria

Area Evaluation Criteria
API integration Correct endpoint, request parameters, and response processing.
State management Appropriate loading, success, and error states.
UI design Clear layout and readable weather information.
Reliability Handles invalid input, connectivity problems, and server errors.
Security Protects credentials and avoids exposing sensitive information.
Code quality Uses reusable components and maintainable code.

21. Interview Questions and Answers

Q1. What is a REST API?

Answer: A REST API is an interface that exposes resources over HTTP and commonly uses methods such as GET, POST, PUT, PATCH, and DELETE.

Q2. Why does a weather application need an API?

Answer: It retrieves weather observations and forecast information from a remote service instead of relying on hardcoded data.

Q3. What is the Fetch API?

Answer: Fetch is a Promise-based JavaScript API used to make HTTP requests and process server responses.

Q4. Why are async and await used?

Answer: They make asynchronous operations easier to write and understand by allowing code to follow a sequential structure.

Q5. What is JSON?

Answer: JSON is a text-based format for exchanging structured data between systems.

Q6. What does response.json() do?

Answer: It reads the response body and parses the JSON text into a JavaScript value.

Q7. Why should response.ok be checked?

Answer: Fetch may resolve even when the server returns an HTTP error status. Checking response.ok allows the application to identify unsuccessful responses.

Q8. How is useState useful in a weather application?

Answer: It stores values such as the search input, weather response, loading status, and error message.

Q9. What is useEffect used for?

Answer: It runs side effects in response to component lifecycle events or changes in dependencies, such as retrieving weather data when a selected city changes.

Q10. Why is a loading indicator important?

Answer: It communicates that a request is in progress and gives users feedback during network delays.

Q11. How should API errors be handled?

Answer: Check response status codes, catch request and parsing errors, display useful messages, and reset loading state in finally.

Q12. Why use encodeURIComponent?

Answer: It encodes a value so it can be safely included in a URL component, such as a city name in a query parameter.

Q13. How can API keys be protected?

Answer: Keep secret credentials on a protected backend when necessary, apply provider-supported restrictions, and monitor usage.

Q14. How can unnecessary API calls be reduced?

Answer: Trigger requests on submission, debounce live search, cache results appropriately, and avoid duplicate requests.

Q15. What is the difference between current weather and a forecast?

Answer: Current weather describes present observations, while forecast data provides predictions for future periods.

22. Practice Exercises

  1. Create a React Native screen with a city input and search button.
  2. Connect the application to a weather REST API.
  3. Display the temperature in Celsius.
  4. Add humidity and wind speed to the weather card.
  5. Show a loading indicator during network requests.
  6. Display a validation message for empty input.
  7. Handle invalid API keys and city-not-found errors.
  8. Move the API request into a separate service module.
  9. Add a refresh button and last-updated timestamp.
  10. Extend the application to display a forecast using FlatList.

23. Quick Revision Checklist

  • REST APIs allow applications to communicate with remote services.
  • GET requests are commonly used to retrieve weather information.
  • API endpoints and parameters must match provider documentation.
  • Fetch sends HTTP requests from React Native.
  • response.ok helps identify unsuccessful HTTP responses.
  • response.json() parses a JSON response body.
  • async and await simplify asynchronous code.
  • useState manages the city, weather, loading, and error values.
  • useEffect can trigger requests when dependencies change.
  • Loading, success, and error states improve usability.
  • Dynamic query parameters should be encoded correctly.
  • API credentials must be managed according to security requirements.
  • Testing should cover invalid input, network failures, and server errors.
  • Reusable components and service modules improve maintainability.
  • Cached weather information should be labelled and timestamped appropriately.

24. Conclusion

Developing a weather application using a REST API is a practical way to learn React Native networking, asynchronous JavaScript, JSON parsing, state management, and interface development. By integrating a weather service, developers can retrieve real weather information and present it through an interactive mobile application.

A reliable weather application should validate user input, handle unsuccessful responses, display loading feedback, protect API credentials, and show the data returned by the server. Additional features such as location-based weather, forecasts, saved cities, and offline caching can make the application more useful.

To continue learning, visit the React Native Training course at JustAcademy, register for the course demo, or explore the JustAcademy website.

whatsapp