{"id":28333,"date":"2025-02-23T20:45:10","date_gmt":"2025-02-23T19:45:10","guid":{"rendered":"https:\/\/www.angulararchitects.io\/blog\/learning-httpresource-with-super-mario\/"},"modified":"2025-06-03T14:54:00","modified_gmt":"2025-06-03T12:54:00","slug":"learning-httpresource-with-super-mario","status":"publish","type":"post","link":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/","title":{"rendered":"Angular&#8217;s new httpResource"},"content":{"rendered":"<div class=\"wp-post-series-box series-signals wp-post-series-box--expandable\">\n\t\t\t<input id=\"collapsible-series-signals6a1b279c8a079\" class=\"wp-post-series-box__toggle_checkbox\" type=\"checkbox\">\n\t\n\t<label\n\t\tclass=\"wp-post-series-box__label\"\n\t\t\t\t\tfor=\"collapsible-series-signals6a1b279c8a079\"\n\t\t\ttabindex=\"0\"\n\t\t\t\t>\n\t\t<p class=\"wp-post-series-box__name wp-post-series-name\">\n\t\t\tThis is post 9 of 9 in the series <em>&ldquo;Signals&rdquo;<\/em>\t\t<\/p>\n\t\t\t<\/label>\n\n\t\t\t<div class=\"wp-post-series-box__posts\">\n\t\t\t<ol>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/angular-signals\/\">Signals in Angular: Building Blocks<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/component-communication-with-signals-inputs-two-way-bindings-and-content-view-queries\/\">Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/successful-with-signals-in-angular-3-effective-rules-for-your-architecture\/\">Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/skillfully-using-signals-in-angular-selected-hints-for-professional-use\/\">Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/when-not-to-use-effects-in-angular-and-what-to-do-instead\/\">When (Not) to use Effects in Angular &#8212; and what to do instead<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/asynchronous-resources-with-angulars-new-resource-api\/\">Asynchronous Data Flow with Angular&#8217;s new Resource API<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/streaming-resources-in-angular-19-2-details-and-semantics\/\">Streaming Resources in Angular &#8211; Details and Semantics<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><a href=\"https:\/\/www.angulararchitects.io\/en\/blog\/streaming-resources-for-a-chat-with-web-sockets-messages-in-a-glitch-free-world\/\">Streaming Resources for a Chat with Web Sockets: Messages in a Glitch-Free World<\/a><\/li>\n\t\t\t\t\t\t\t\t\t<li><span class=\"wp-post-series-box__current\">Angular&#8217;s new httpResource<\/span><\/li>\n\t\t\t\t\t\t\t<\/ol>\n\t\t<\/div>\n\t<\/div>\n<h1>Learning httpResource with Super Mario<\/h1>\n<p>Angular 19.2 comes with the new <code>httpResource<\/code> that fetches data within the reactive flow. This article shows how to use this -- currently experimental -- feature by implementing a simple application scrolling through levels in the style of the traditional Super Mario game.<\/p>\n<p>Each level consists of tiles that are available in 4 different styles -- Overworld, Underground, Underwater, and Castle -- we can freely choose from:<\/p>\n<p><video src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/ngMario.mp4\" autoplay loop muted style=\"width:100%\"><\/video><\/p>\n<p>The \ud83d\udcc2 <a href=\"https:\/\/github.com\/manfredsteyer\/mario.git\">source code<\/a> provides the shown component that takes care of loading level files (JSON) and tiles for drawing the levels via <code>httpResource<\/code>. For rendering and animating the levels, the code also <strong>contains<\/strong> a very simple <strong>&quot;engine&quot;<\/strong> treated as a <strong>black box<\/strong> by this article.<\/p>\n<h2>Level Files<\/h2>\n<p>The different levels are represented by JSON files defining which tiles, such as the floor or a cloud, are shown at which coordinates:<\/p>\n<pre><code class=\"language-json\">{\n  &quot;levelId&quot;: 1,\n  &quot;backgroundColor&quot;: &quot;#9494ff&quot;,\n  &quot;items&quot;: [\n    { &quot;tileKey&quot;: &quot;floor&quot;, &quot;col&quot;: 0, &quot;row&quot;: 13, [...] },\n    { &quot;tileKey&quot;: &quot;cloud&quot;, &quot;col&quot;: 12, &quot;row&quot;: 1, [...] },\n    [...]\n  ]\n}<\/code><\/pre>\n<p>The coordinates define the position within a matrix of blocks with 16x16 pixels. Besides these level files, there is an <code>overview.json<\/code> informing about the levels available:<\/p>\n<pre><code class=\"language-json\">{\n  &quot;levels&quot;: [\n {\n      &quot;levelKey&quot;: &quot;01&quot;,\n      &quot;title&quot;: &quot;Level 1&quot;\n },\n {\n      &quot;levelKey&quot;: &quot;02&quot;,\n      &quot;title&quot;: &quot;Level 2&quot;\n },\n [...]\n ]\n}<\/code><\/pre>\n<h2>Loading JSON with ngResource<\/h2>\n<p>To abstract the data access, hiding the creation of the <code>httpResource<\/code> in a service is a good idea:<\/p>\n<pre><code class=\"language-ts\">@Injectable({ providedIn: &#039;root&#039; })\nexport class LevelLoader {\n  getLevelOverviewResource(): HttpResourceRef&lt;LevelOverview&gt; {\n    return httpResource&lt;LevelOverview&gt;(() =&gt; &#039;\/levels\/overview.json&#039;, {\n      defaultValue: initLevelOverview,\n    });\n  }\n\n  getLevelResource(levelKey: () =&gt; string | undefined): HttpResourceRef&lt;Level&gt; {\n    return httpResource&lt;Level&gt;(() =&gt; !levelKey() ? undefined : <code>\/levels\/${levelKey()}.json<\/code>, {\n      defaultValue: initLevel,\n    });\n  }\n\n [...]\n}<\/code><\/pre>\n<p>The options object taken by the 2nd parameter allows the definition of a default value that is used before the resource has been loaded.<\/p>\n<p>To define which level to load, <code>getLevelResource<\/code> expects a Signal that returns a level key from which the service derives the file name. This read-only Signal is represented by the general abstraction <code>() =&gt; string | undefined<\/code>.<\/p>\n<p>Please note that the URL passed to <code>getLevelResource<\/code> is represented by a <strong>lambda expression.<\/strong> This is necessary to make the resource <strong>automatically recompute<\/strong> the URL when the included <code>levelKey<\/code> Signal changes. Underneath the covers, <code>httpResource<\/code> uses this lambda expression to construct a Computed Signal acting as the trigger: Every time this trigger changes, the resource loads the URL.<\/p>\n<p>To prevent triggering the <code>httpResource<\/code>, this expression needs to return <code>undefined<\/code>. This is necessary when the application needs to postpone loading until specific parameters, such as the <code>levelKey<\/code>, become available.<\/p>\n<h2>More Options with Explicit HttpResourceRequest<\/h2>\n<p>To get more control over the HTTP request issued, the caller can pass a <code>HttpResourceRequest<\/code> instead of a URL:<\/p>\n<pre><code class=\"language-ts\">getLevelResource(levelKey: () =&gt; string) {\n  return httpResource&lt;Level&gt;(\n    () =&gt; ({\n      url: <code>\/levels\/${levelKey()}.json<\/code>,\n      method: &quot;GET&quot;,\n      headers: {\n        accept: &quot;application\/json&quot;,\n      },\n      params: {\n        levelId: levelKey(),\n      },\n      reportProgress: false,\n      body: null,\n      transferCache: false,\n      withCredentials: false,\n    }),\n    { defaultValue: initLevel }\n  );\n}<\/code><\/pre>\n<p>Also, this <code>HttpResourceRequest<\/code> can be represented by a lambda expression with which the <code>httpResource<\/code> internally constructs a Computed Signal.<\/p>\n<p>It's important to note that the <code>httpResource<\/code> is <strong>only intended for fetching data,<\/strong> even though we can define a method (HTTP verb) beyond <code>GET<\/code> and a <code>body<\/code> transmitted as the payload. This option allows the consumption of Web APIs that don't align with the semantics of HTTP verbs. By default, the passed <code>body<\/code> is converted to JSON. However, this option is not designed to write data back to the server. This task is not covered by the <code>httpResource<\/code>. Also, while the automatic use of <code>switchMap<\/code> semantics fits for fetching data, it is very likely the wrong behavior for writing data back to the server.<\/p>\n<p>Using the <code>reportProgress<\/code> option, the caller can request information about the progress of the current operation. This comes in handy when downloading larger files. The section below provides an example of this.<\/p>\n<h2>More on this: Angular Architecture Workshop (Remote, Interactive, Advanced)<\/h2>\n<p>Become an expert for enterprise-scale and maintainable Angular applications with our <a href=\"https:\/\/www.angulararchitects.io\/en\/angular-workshops\/advanced-angular-enterprise-architecture-incl-ivy\/\">Angular Architecture workshop!<\/a><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/sujet-en.jpg\" alt=\"\" \/><\/p>\n<p><a href=\"https:\/\/www.angulararchitects.io\/en\/angular-workshops\/advanced-angular-enterprise-architecture-incl-ivy\/\">English Version<\/a> | <a href=\"https:\/\/www.angulararchitects.io\/schulungen\/advanced-angular-enterprise-anwendungen-und-architektur\/\">German Version<\/a><\/p>\n<h2>Parsing and Validating the Received Data<\/h2>\n<p>By default, the <code>httpResource<\/code> expects JSON that fits the provided type parameter. Hence, after parsing the fetched JSON it just uses a type assertion to make TypeScript assume the specified type.<\/p>\n<p>However, it's possible to hook into this process to provide custom logic for validating the received raw value and converting it to the type specified by the type parameter. For this, the caller can define a <code>parse<\/code> function in the options object:<\/p>\n<pre><code class=\"language-ts\">getLevelResourceAlternative(levelKey: () =&gt; string) {\n  return httpResource&lt;Level&gt;(() =&gt; <code>\/levels\/${levelKey()}.json<\/code>, {\n    defaultValue: initLevel,\n    parse: (raw) =&gt; {\n      return toLevel(raw);\n    },\n  });\n}<\/code><\/pre>\n<p>The <code>httpResource<\/code> converts the received JSON to an object of type <code>unknown<\/code> that is passed to <code>parse<\/code>. In our example, a simple hand-written <code>toLevel<\/code> function is used. However, <code>parse<\/code> can also be used to connect the resource to a library specialized in schema validation such as <a href=\"https:\/\/zod.dev\/\">Zod<\/a>.<\/p>\n<h2>Loading Data Beyond JSON<\/h2>\n<p>While the <code>httpResource<\/code> expects JSON converted to a JavaScript object by default, the caller can also request other data representations:<\/p>\n<ul>\n<li><code>httpResource.text<\/code> returns plain text<\/li>\n<li><code>httpResource.blob<\/code> returns the fetched data as a Blob<\/li>\n<li><code>httpResource.arrayBuffer<\/code> returns the fetched data as an ArrayBuffer<\/li>\n<\/ul>\n<p>To demonstrate this, the example requests an image with all the possible tiles as a Blob. From this Blog, you can derive the needed tiles for the chosen level style.<\/p>\n<p>The following image shows a section of this tiles map and shows that the example can easily switch between the different styles by using a horizontal or vertical offset:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/tile-map.png\" alt=\"Section of the tiles map used by the example\" \/><\/p>\n<p>This tiles map was taken from <a href=\"https:\/\/www.spriters-resource.com\/nes\/supermariobros\/sheet\/52571\">here<\/a>. For loading the tiles map, a <code>TilesMapLoader<\/code> delegates to <code>httpResource.blob<\/code>:<\/p>\n<pre><code class=\"language-ts\">@Injectable({ providedIn: &quot;root&quot; })\nexport class TilesMapLoader {\n  getTilesMapResource(): HttpResourceRef&lt;Blob | undefined&gt; {\n    return httpResource.blob(() =&gt; {\n      url: &quot;\/tiles.png&quot;,\n      reportProgress: true,\n    });\n  }\n}<\/code><\/pre>\n<p>This resource also requests progress information the example picks up for displaying the progress information on the left of the dropdown fields.<\/p>\n<h2>Side Note: HttpClient Under the Covers Allows to Use Interceptors<\/h2>\n<p>Under the covers, the new <code>httpResource<\/code> is currently using the <code>HttpClient<\/code>. Hence, we need to provide the HttpClient, which is usually done by using <code>provideHttpClient<\/code> during bootstrapping. As a consequence, the <code>httpResource<\/code> also automatically leverages registered <code>HttpInterceptors<\/code>.<\/p>\n<p>However, using the <code>HttpClient<\/code> is an implementation detail that might eventually be switched out by another implementation.<\/p>\n<h2>Putting Everything Together: Reactive Flow<\/h2>\n<p>Now, as we have factories for all <code>httpResource<\/code>s, we can define our reactive graph:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/06\/graph-scaled.png\" alt=\"Reactive Flow of ngMario\" \/><\/p>\n<p>The Signals <code>levelKey<\/code>, <code>style<\/code>, and <code>animation<\/code> represent the user input. The former two correspond with the dropdown fields on the top. The Signal <code>animation<\/code> contains a <code>boolean<\/code> informing whether the animation has been started by clicking the <code>Toggle Animation<\/code> button (see screenshot above).<\/p>\n<p>The <code>tilesResource<\/code> in the upper middle is a classic resource that derives the individual tiles for the chosen style. For this, it basically delegates to a function provided by the game &quot;engine&quot;, treated as a black box here.<\/p>\n<p>The rendering is invoked by an effect as we cannot directly draw the level using data binding. It is drawing or animating the level on a canvas provided as a Signal-based <code>viewChild<\/code>. This effect is invoked whenever the <code>level<\/code> (provided by the <code>levelResource<\/code>), the <code>style<\/code>, the <code>animation<\/code> flag, or the <code>canvas<\/code> is changing.<\/p>\n<p>A <code>tilesMapProgress<\/code> Signal uses the progress information provided by the <code>tilesMapResource<\/code> to indicate how much of the tiles map has already been downloaded. For loading the list with the levels available, the example uses an <code>levelOverviewResource<\/code> that is not directly connected with the so far discussed reactive graph.<\/p>\n<p>The following listing shows the implementation of this reactive flow in the form of members used by the <code>LevelComponent<\/code>:<\/p>\n<pre><code class=\"language-ts\">export class LevelComponent implements OnDestroy {\n  private tilesMapLoader = inject(TilesMapLoader);\n  private levelLoader = inject(LevelLoader);\n\n  canvas = viewChild&lt;ElementRef&lt;HTMLCanvasElement&gt;&gt;(&quot;canvas&quot;);\n\n  levelKey = linkedSignal&lt;string | undefined&gt;(() =&gt; this.getFirstLevelKey());\n  style = signal&lt;Style&gt;(&quot;overworld&quot;);\n  animation = signal(false);\n\n  tilesMapResource = this.tilesMapLoader.getTilesMapResource();\n  levelResource = this.levelLoader.getLevelResource(this.levelKey);\n  levelOverviewResource = this.levelLoader.getLevelOverviewResource();\n\n  tilesResource = createTilesResource(this.tilesMapResource, this.style);\n\n  tilesMapProgress = computed(() =&gt;\n    calcProgress(this.tilesMapResource.progress())\n  );\n\n  constructor() {\n    [...]\n    effect(() =&gt; {\n      this.render();\n    });\n  }\n\n  reload() {\n    this.tilesMapResource.reload();\n    this.levelResource.reload();\n  }\n\n  private getFirstLevelKey(): string | undefined {\n    return this.levelOverviewResource.value()?.levels?.[0]?.levelKey;\n  }\n\n  [...]\n}<\/code><\/pre>\n<p>Using a <code>linkedSignal<\/code> for the <code>levelKey<\/code> allows us to use the first level as the default value once the list with the levels is loaded. The helper <code>getFirstLevelKey<\/code> returns this one from the <code>levelOverviewResource<\/code>.<\/p>\n<p>The render Effect is basically retrieving the mentioned values and delegating to the &quot;engines&quot; <code>animateLevel<\/code> or <code>rederLevel<\/code> function:<\/p>\n<pre><code class=\"language-ts\">private render() {\n  const tiles = this.tilesResource.value();\n  const level = this.levelResource.value();\n  const canvas = this.canvas()?.nativeElement;\n  const animation = this.animation();\n\n  if (!tiles || !canvas) {\n    return;\n  }\n\n  if (animation) {\n    animateLevel({\n      canvas,\n      level,\n      tiles,\n    });\n  } else {\n    renderLevel({\n      canvas,\n      level,\n      tiles,\n    });\n  }\n}<\/code><\/pre>\n<h2>Resources and Missing Parameters<\/h2>\n<p>The <code>tilesResource<\/code> displayed in the diagram above basically delegates to the asynchronous function <code>extractTiles<\/code> which is also provided by the game &quot;engine&quot;:<\/p>\n<pre><code class=\"language-ts\">function createTilesResource(\n  tilesMapResource: HttpResourceRef&lt;Blob | undefined&gt;,\n  style: () =&gt; Style\n) {\n  const tilesMap = tilesMapResource.value();\n\n  \/\/ undefined prevents the resource from beeing triggered\n  const params = computed(() =&gt;\n    !tilesMap\n      ? undefined\n      : {\n          tilesMap: tilesMap,\n          style: style(),\n        }\n  );\n\n  return resource({\n    params,\n    loader: (loaderParams) =&gt; {\n      const { tilesMap, style } = loaderParams.params;\n      return extractTiles(tilesMap, style);\n    },\n  });\n}<\/code><\/pre>\n<p>This simple resource contains a noteworthy detail: Until the tile map has been loaded, the <code>tilesMapResource<\/code>'s <code>value<\/code> is <code>undefined<\/code>. However, without a <code>tilesMap<\/code>, we cannot invoke <code>extractTiles<\/code> and hence trigger the <code>tilesResource<\/code>. This is respected by the <code>params<\/code> Signal: It also returns <code>undefined<\/code> in this case so that the <strong>loader<\/strong> is <strong>not invoked.<\/strong><\/p>\n<h2>Displaying the Progress<\/h2>\n<p>Above, the <code>tilesMapResource<\/code> was configured to provide information about the download progress via its <code>progress<\/code> Signal. Using a computed Signal in the <code>LevelComponent<\/code>, it is projected to a string:<\/p>\n<pre><code class=\"language-ts\">function calcProgress(progress: HttpProgressEvent | undefined): string {\n  if (!progress) {\n    return &quot;-&quot;;\n  }\n\n  if (progress.total) {\n    const percent = Math.round((progress.loaded \/ progress.total) * 100);\n    return percent + &quot;%&quot;;\n  }\n\n  const kb = Math.round(progress.loaded \/ 1024);\n  return kb + &quot; KB&quot;;\n}<\/code><\/pre>\n<p>If the server provides the total file size, this function calculates the downloaded percentage. Otherwise it just displays the amount of downloaded kilobytes. Before starting the download, there is no progress information. In this case, a dash is returned.<\/p>\n<p>To test this feature, you can throttle the browser's network connection in the dev tools and press the <code>reload<\/code> button to invoke the resource's <code>reload<\/code> method.<\/p>\n<h2>Status, Headers, Error and More<\/h2>\n<p>For the case the application needs to know about the status code or the headers we've received, the <code>httpResource<\/code> provides respective Signals:<\/p>\n<pre><code class=\"language-ts\">console.log(&quot;status&quot;, this.levelOverviewResource.status());\nconsole.log(&quot;statusCode&quot;, this.levelOverviewResource.statusCode());\nconsole.log(&quot;headers&quot;, this.levelOverviewResource.headers()?.keys());<\/code><\/pre>\n<p>Besides this, the <code>httpResource<\/code> provides everything we already know from ordinary resources, such as an <code>error<\/code> Signal informing about a potential error or the possibility of updating the <code>value<\/code> that is treated as a local working copy. That also means that the value is not automatically written back to the server. This task still needs to be implemented in a classic way.<\/p>\n<h2>Conclusion<\/h2>\n<p>The new <code>httpResource<\/code> is another building block complementing Angular's new reactivity story. It allows data to be loaded within the reactive graph. Currently, it uses the <code>HttpClient<\/code> as an implementation detail that might eventually be switched out by another solution.<\/p>\n<p>While the <code>HTTP resource<\/code> also allows fetching data using HTTP verbs beyond GET, e.g., with POST calls, it is not intended for writing data back to the server. This task still needs to be done in the traditional way.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is post 9 of 9 in the series &ldquo;Signals&rdquo; Signals in Angular: Building Blocks Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use When (Not) to use Effects in [&hellip;]<\/p>\n","protected":false},"author":25,"featured_media":28335,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"_price":"","_stock":"","_tribe_ticket_header":"","_tribe_default_ticket_provider":"","_ticket_start_date":"","_ticket_end_date":"","_tribe_ticket_show_description":"","_tribe_ticket_show_not_going":false,"_tribe_ticket_use_global_stock":"","_tribe_ticket_global_stock_level":"","_global_stock_mode":"","_global_stock_cap":"","_tribe_rsvp_for_event":"","_tribe_ticket_going_count":"","_tribe_ticket_not_going_count":"","_tribe_tickets_list":"[]","_tribe_ticket_has_attendee_info_fields":false,"footnotes":""},"categories":[18],"tags":[],"class_list":["post-28333","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized","post_series-signals"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Angular&#039;s new httpResource - ANGULARarchitects<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Angular&#039;s new httpResource - ANGULARarchitects\" \/>\n<meta property=\"og:description\" content=\"This is post 9 of 9 in the series &ldquo;Signals&rdquo; Signals in Angular: Building Blocks Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use When (Not) to use Effects in [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\" \/>\n<meta property=\"og:site_name\" content=\"ANGULARarchitects\" \/>\n<meta property=\"article:published_time\" content=\"2025-02-23T19:45:10+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-03T12:54:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/httpResource-sujet.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1200\" \/>\n\t<meta property=\"og:image:height\" content=\"628\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Manfred Steyer\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:image\" content=\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/httpResource-sujet.jpg\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Manfred Steyer\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\"},\"author\":{\"name\":\"Manfred Steyer\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\"},\"headline\":\"Angular&#8217;s new httpResource\",\"datePublished\":\"2025-02-23T19:45:10+00:00\",\"dateModified\":\"2025-06-03T12:54:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\"},\"wordCount\":1421,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png\",\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\",\"name\":\"Angular's new httpResource - ANGULARarchitects\",\"isPartOf\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png\",\"datePublished\":\"2025-02-23T19:45:10+00:00\",\"dateModified\":\"2025-06-03T12:54:00+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png\",\"width\":3456,\"height\":1442},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.angulararchitects.io\/en\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Angular&#8217;s new httpResource\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#website\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"name\":\"ANGULARarchitects\",\"description\":\"AngularArchitects.io\",\"publisher\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#organization\",\"name\":\"ANGULARarchitects\",\"alternateName\":\"SOFTWAREarchitects\",\"url\":\"https:\/\/www.angulararchitects.io\/en\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"contentUrl\":\"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg\",\"width\":644,\"height\":216,\"caption\":\"ANGULARarchitects\"},\"image\":{\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/github.com\/angular-architects\",\"https:\/\/www.linkedin.com\/company\/angular-architects\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a\",\"name\":\"Manfred Steyer\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g\",\"caption\":\"Manfred Steyer\"}}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Angular's new httpResource - ANGULARarchitects","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/","og_locale":"en_US","og_type":"article","og_title":"Angular's new httpResource - ANGULARarchitects","og_description":"This is post 9 of 9 in the series &ldquo;Signals&rdquo; Signals in Angular: Building Blocks Component Communication with Signals: Inputs, Two-Way Bindings, and Content\/ View Queries Successful with Signals in Angular &#8211; 3 Effective Rules for Your Architecture Skillfully Using Signals in Angular &#8211; Selected Hints for Professional Use When (Not) to use Effects in [&hellip;]","og_url":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/","og_site_name":"ANGULARarchitects","article_published_time":"2025-02-23T19:45:10+00:00","article_modified_time":"2025-06-03T12:54:00+00:00","og_image":[{"width":1200,"height":628,"url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/httpResource-sujet.jpg","type":"image\/jpeg"}],"author":"Manfred Steyer","twitter_card":"summary_large_image","twitter_image":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/httpResource-sujet.jpg","twitter_misc":{"Written by":"Manfred Steyer","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#article","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/"},"author":{"name":"Manfred Steyer","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a"},"headline":"Angular&#8217;s new httpResource","datePublished":"2025-02-23T19:45:10+00:00","dateModified":"2025-06-03T12:54:00+00:00","mainEntityOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/"},"wordCount":1421,"commentCount":0,"publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png","inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/","url":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/","name":"Angular's new httpResource - ANGULARarchitects","isPartOf":{"@id":"https:\/\/www.angulararchitects.io\/en\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage"},"thumbnailUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png","datePublished":"2025-02-23T19:45:10+00:00","dateModified":"2025-06-03T12:54:00+00:00","breadcrumb":{"@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#primaryimage","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2025\/02\/mario2.png","width":3456,"height":1442},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulararchitects.io\/en\/blog\/learning-httpresource-with-super-mario\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.angulararchitects.io\/en\/"},{"@type":"ListItem","position":2,"name":"Angular&#8217;s new httpResource"}]},{"@type":"WebSite","@id":"https:\/\/www.angulararchitects.io\/en\/#website","url":"https:\/\/www.angulararchitects.io\/en\/","name":"ANGULARarchitects","description":"AngularArchitects.io","publisher":{"@id":"https:\/\/www.angulararchitects.io\/en\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.angulararchitects.io\/en\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.angulararchitects.io\/en\/#organization","name":"ANGULARarchitects","alternateName":"SOFTWAREarchitects","url":"https:\/\/www.angulararchitects.io\/en\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/","url":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","contentUrl":"https:\/\/www.angulararchitects.io\/wp-content\/uploads\/2023\/07\/AA-Logo-RGB-horizontal-inside-knowledge-black.svg","width":644,"height":216,"caption":"ANGULARarchitects"},"image":{"@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/github.com\/angular-architects","https:\/\/www.linkedin.com\/company\/angular-architects\/"]},{"@type":"Person","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/f3de69c1e2bdb5ba04d8d2f5f998b81a","name":"Manfred Steyer","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.angulararchitects.io\/en\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/8778dfb353992fa3a0d909beee085a088891e5bfce65cdb3631801da527cf11b?s=96&d=mm&r=g","caption":"Manfred Steyer"}}]}},"_links":{"self":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/28333","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/users\/25"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/comments?post=28333"}],"version-history":[{"count":10,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/28333\/revisions"}],"predecessor-version":[{"id":30460,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/posts\/28333\/revisions\/30460"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media\/28335"}],"wp:attachment":[{"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/media?parent=28333"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/categories?post=28333"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulararchitects.io\/en\/wp-json\/wp\/v2\/tags?post=28333"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}