APPROACH 2: fl::task::await_top_level() pattern (synchronous-style async code) This approach blocks until completion - feels like traditional programming
| 162 | // APPROACH 2: fl::task::await_top_level() pattern (synchronous-style async code) |
| 163 | // This approach blocks until completion - feels like traditional programming |
| 164 | void test_await_approach() { |
| 165 | FL_WARN("APPROACH 2: await_top_level pattern with explicit types"); |
| 166 | |
| 167 | // TUTORIAL: Create a FetchOptions object to configure the HTTP request |
| 168 | // FetchOptions is a data container - you can set timeout, headers, etc. |
| 169 | fl::net::http::FetchOptions request_config(""); // Empty URL - will use the URL passed to fetch_get() |
| 170 | request_config.timeout(5000) // 5 second timeout |
| 171 | .header("User-Agent", "FastLED/Client-Tutorial"); // Custom user agent |
| 172 | |
| 173 | // TUTORIAL: fetch_get() returns fl::task::Promise<fl::net::http::Response> (explicit type!) |
| 174 | // This promise represents the future HTTP response |
| 175 | fl::task::Promise<fl::net::http::Response> http_promise = fl::net::http::fetch_get("http://fastled.io", request_config); |
| 176 | |
| 177 | // TUTORIAL: await_top_level() returns fl::task::PromiseResult<fl::net::http::Response> |
| 178 | // result wraps either a successful response OR an Error - never both! |
| 179 | // CRITICAL: await_top_level() blocks until completion - ONLY safe in Arduino loop()! |
| 180 | fl::task::PromiseResult<fl::net::http::Response> result = fl::task::await_top_level(http_promise); |
| 181 | |
| 182 | // TUTORIAL: Check if the result contains a successful response |
| 183 | if (result.ok()) { |
| 184 | // TUTORIAL: Extract the response from the result |
| 185 | // result.value() returns const fl::net::http::Response& - the actual HTTP response |
| 186 | const fl::net::http::Response& http_response = result.value(); |
| 187 | |
| 188 | FL_WARN("SUCCESS [Await] HTTP fetch successful! Status: " |
| 189 | << http_response.status() << " " << http_response.status_text()); |
| 190 | |
| 191 | // TUTORIAL: Check for optional Content-Type header |
| 192 | // get_content_type() returns fl::optional<fl::string> - may be empty! |
| 193 | fl::optional<fl::string> content_type = http_response.get_content_type(); |
| 194 | if (content_type.has_value()) { |
| 195 | FL_WARN("CONTENT [Await] Content-Type: " << *content_type); |
| 196 | } |
| 197 | |
| 198 | // TUTORIAL: Get the response body as fl::string |
| 199 | const fl::string& response_body = http_response.text(); |
| 200 | if (response_body.length() >= 100) { |
| 201 | FL_WARN("RESPONSE [Await] First 100 characters: " << response_body.substr(0, 100)); |
| 202 | } else { |
| 203 | FL_WARN("RESPONSE [Await] Full response (" << response_body.length() |
| 204 | << " chars): " << response_body); |
| 205 | } |
| 206 | |
| 207 | // Visual feedback: Blue LEDs indicate await-based success (different from promise) |
| 208 | fill_solid(leds, NUM_LEDS, fl::CRGB(0, 0, 64)); // Blue for await success |
| 209 | } else { |
| 210 | // Either HTTP error OR network error - both end up here |
| 211 | // TUTORIAL: result.error_message() is a convenience method for getting error text |
| 212 | FL_WARN("ERROR [Await] Request failed: " << result.error_message()); |
| 213 | |
| 214 | // Visual feedback: Red LEDs for any await error |
| 215 | fill_solid(leds, NUM_LEDS, fl::CRGB(64, 0, 0)); // Red for any error |
| 216 | } |
| 217 | } |
| 218 | |
| 219 | /// APPROACH 3: JSON Response Handling with FastLED's ideal JSON API |
| 220 | /// This demonstrates fetch responses with automatic JSON parsing |
no test coverage detected