APPROACH 4: JSON Response with await pattern Same JSON handling but using await_top_level for synchronous-style code
| 284 | /// APPROACH 4: JSON Response with await pattern |
| 285 | /// Same JSON handling but using await_top_level for synchronous-style code |
| 286 | void test_json_await() { |
| 287 | FL_WARN("APPROACH 4: JSON Response with await pattern"); |
| 288 | |
| 289 | // TUTORIAL: Using await pattern with JSON responses |
| 290 | // fl::net::http::fetch_get() returns fl::task::Promise<fl::net::http::Response> |
| 291 | fl::task::Promise<fl::net::http::Response> json_promise = fl::net::http::fetch_get("https://httpbin.org/get"); |
| 292 | |
| 293 | // TUTORIAL: await_top_level() converts promise to result |
| 294 | // fl::task::PromiseResult<fl::net::http::Response> contains either response or error |
| 295 | fl::task::PromiseResult<fl::net::http::Response> result = fl::task::await_top_level(json_promise); |
| 296 | |
| 297 | if (result.ok()) { |
| 298 | // TUTORIAL: Extract the response from the result |
| 299 | const fl::net::http::Response& http_response = result.value(); |
| 300 | |
| 301 | FL_WARN("SUCCESS [JSON Await] HTTP fetch successful! Status: " |
| 302 | << http_response.status() << " " << http_response.status_text()); |
| 303 | |
| 304 | // TUTORIAL: Check for JSON content and parse if available |
| 305 | if (http_response.is_json()) { |
| 306 | FL_WARN("DETECTED [JSON Await] Response contains JSON data"); |
| 307 | |
| 308 | // TUTORIAL: Parse JSON with automatic caching |
| 309 | fl::json data = http_response.json(); |
| 310 | |
| 311 | // TUTORIAL: httpbin.org/get returns information about the request |
| 312 | // Extract data with safe defaults using FastLED's ideal JSON API |
| 313 | fl::string origin_ip = data["origin"] | fl::string("unknown"); |
| 314 | fl::string request_url = data["url"] | fl::string("unknown"); |
| 315 | |
| 316 | FL_WARN("JSON [Await] Request Origin IP: " << origin_ip); |
| 317 | FL_WARN("JSON [Await] Request URL: " << request_url); |
| 318 | |
| 319 | // TUTORIAL: Access nested headers object safely |
| 320 | if (data.contains("headers")) { |
| 321 | fl::json headers = data["headers"]; |
| 322 | fl::string user_agent = headers["User-Agent"] | fl::string("unknown"); |
| 323 | fl::string accept = headers["Accept"] | fl::string("unknown"); |
| 324 | |
| 325 | FL_WARN("JSON [Await] User-Agent: " << user_agent); |
| 326 | FL_WARN("JSON [Await] Accept: " << accept); |
| 327 | } |
| 328 | |
| 329 | // TUTORIAL: Access query parameters (if any) |
| 330 | if (data.contains("args")) { |
| 331 | fl::json args = data["args"]; |
| 332 | if (args.size() > 0) { |
| 333 | FL_WARN("JSON [Await] Query parameters found: " << args.size()); |
| 334 | } else { |
| 335 | FL_WARN("JSON [Await] No query parameters in request"); |
| 336 | } |
| 337 | } |
| 338 | |
| 339 | // Visual feedback: Cyan LEDs for successful await JSON processing |
| 340 | fill_solid(leds, NUM_LEDS, fl::CRGB(0, 128, 128)); // Cyan for await JSON success |
| 341 | |
| 342 | } else { |
| 343 | FL_WARN("INFO [JSON Await] Response is not JSON format"); |
no test coverage detected