Last active
November 12, 2023 16:44
-
-
Save bwnyasse/c131ae5d7f74439d15119826ff635906 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Dart & Flutter - Training | |
* Workshop: Advanced Dart Programming - HTTP Requests, Streams, and Mixins | |
* Copyright (Boris-Wilfried Nyasse) | |
* All rights reserved | |
* | |
* Workshop Goals and Objectives: | |
* - Implement HTTP requests to fetch data from an external API. | |
* - Use mixins for data formatting. | |
* - Understand and utilize streams for asynchronous data processing. | |
* - Apply advanced Dart features in a real-world scenario. | |
* | |
* In this workshop, you'll build a program that fetches movie data from an API | |
* and processes it using Dart's advanced features like HTTP requests, streams, and mixins. | |
* | |
* Follow the FIXMEs and TODOs to complete the workshop. | |
*/ | |
import 'dart:async'; | |
import 'dart:convert'; | |
import 'package:http/http.dart' as http; | |
// Mixin for formatting movie data. | |
mixin MovieFormatter { | |
// Formats the movie data into a readable string. | |
String formatMovieData( | |
String title, | |
String releaseDate, | |
double popularity, | |
) { | |
return '''Movie: | |
$title | |
Release Date: $releaseDate | |
Popularity: $popularity'''; | |
} | |
} | |
// Movie class | |
class Movie { | |
String title; | |
String releaseDate; | |
double popularity; | |
// Constructor with optional named parameters for movie properties. | |
Movie({ | |
this.title = 'Unknown', | |
this.releaseDate = 'N/A', | |
this.popularity = 0.0, | |
}); | |
// Overridden toString method using the formatMovieData function from the mixin. | |
@override | |
String toString() { | |
// FIXME: 1- Ensure the Movie class correctly implements the MovieFormatter mixin to use the formatMovieData method. | |
return formatMovieData(title, releaseDate, popularity); | |
} | |
} | |
// Fetches the first movie from the API and returns a Movie object. | |
Future<Movie> fetchFirstMovie() async { | |
const apiKey = '4205ec1d93b1e3465f636f0956a98c64'; | |
const api = 'https://api.themoviedb.org/3'; | |
const urlPath = 'movie/now_playing'; | |
final url = Uri.parse('$api/$urlPath?api_key=$apiKey&language=en-US'); | |
try { | |
final response = http.get(url); | |
// FIXME: 2- Modify the http.get(url) call to properly handle the asynchronous HTTP request and fetch the response. | |
if (response.statusCode == 200) { | |
var data = json.decode(response.body); | |
var firstMovieData = data['results'][0]; | |
return Movie( | |
title: firstMovieData['title'] ?? 'No title', | |
releaseDate: firstMovieData['release_date'] ?? 'No release date', | |
popularity: firstMovieData['popularity'] ?? 0.0, | |
); | |
} else { | |
print('Request failed with status: ${response.statusCode}.'); | |
return Movie(); | |
} | |
} catch (e) { | |
print("Error fetching movie: $e"); | |
return Movie(); | |
} | |
} | |
// Stream of movies, simulating asynchronous fetching of movies. | |
// FIXME: 3- Update the movieStream function's signature to accurately represent it as an asynchronous stream generator. | |
Stream<Movie> movieStream() async { | |
for (int i = 0; i < 5; i++) { | |
await Future.delayed(const Duration(seconds: 1)); | |
yield await fetchFirstMovie(); | |
} | |
} | |
// Main function to run the workshop code. | |
void main() async { | |
print('Starting movie stream...'); | |
// TODO: 4- Write a loop in the main function to iterate over the movieStream and print details for each movie. | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment