{"id":2009,"date":"2024-03-13T05:00:00","date_gmt":"2024-03-13T12:00:00","guid":{"rendered":"https:\/\/www.angulartraining.com\/daily-newsletter\/?p=2009"},"modified":"2024-03-12T14:57:23","modified_gmt":"2024-03-12T21:57:23","slug":"code-challenge-3-solution","status":"publish","type":"post","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/","title":{"rendered":"Code challenge #3 solution"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Before I dive into the solution of <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-rxjs-wizardry\/\" target=\"_blank\" rel=\"noopener\" title=\"\">code challenge #3<\/a>, I wanted to mention that my next <a href=\"https:\/\/courses.angulartraining.com\/course\/monthly-online-workshops\" target=\"_blank\" rel=\"noopener\" title=\"\">FREE workshop<\/a> is scheduled for April 4th. It will be all about <strong>getting into RxJs from scratch<\/strong>, and you can <a href=\"https:\/\/courses.angulartraining.com\/course\/monthly-online-workshops\" target=\"_blank\" rel=\"noopener\" title=\"\">register here<\/a>. I&#8217;ll start from the basics and move on to more advanced topics, such as subjects and operators, and you&#8217;ll be able to ask me questions as we go through the content and exercises together.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As always, it&#8217;s a free workshop, but your <a href=\"https:\/\/www.buymeacoffee.com\/angulartraining\" target=\"_blank\" rel=\"noopener\" title=\"\">coffee donations are always welcome<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s get into our code challenge solution. The goal was to &#8220;connect&#8221; two different dropdowns so that the selection of the first dropdown (a continent) would update the contents of the second dropdown (a list of countries for that continent):<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"382\" height=\"380\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-1.png\" alt=\"\" class=\"wp-image-2010\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-1.png 382w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-1-300x298.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-1-150x150.png 150w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-1-60x60.png 60w\" sizes=\"auto, (max-width: 382px) 100vw, 382px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The challenge is that countries depend on two different Observable data sources:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>An HTTP request to an API to get the list of all countries in the world<\/li>\n\n\n\n<li>The currently selected continent (a reactive form <code>select<\/code> dropdown)<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">In other words, we start with the following code:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"834\" height=\"215\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-2.png\" alt=\"\" class=\"wp-image-2011\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-2.png 834w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-2-300x77.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-2-768x198.png 768w\" sizes=\"auto, (max-width: 834px) 100vw, 834px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Our goal is to combine data from both Observables into one result. Ideally, such a result would be updated whenever any of the Observable sources are updated (e.g., a new continent is selected by the user, or a new list of countries is available from the API).<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As a result, we can use the <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/rxjs-withlatestfrom-operator\/\" target=\"_blank\" rel=\"noopener\" title=\"\">withLatestFrom<\/a> operator to make that &#8220;connection&#8221; between our two Observables:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"889\" height=\"74\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-3.png\" alt=\"\" class=\"wp-image-2012\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-3.png 889w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-3-300x25.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-3-768x64.png 768w\" sizes=\"auto, (max-width: 889px) 100vw, 889px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Such an operator returns an array of all the latest values of our source Observables in the order in which they were declared. As a result, we can use the <code>map<\/code> operator to receive that array and turn it into something different:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"890\" height=\"122\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-4.png\" alt=\"\" class=\"wp-image-2013\" style=\"width:840px;height:auto\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-4.png 890w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-4-300x41.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-4-768x105.png 768w\" sizes=\"auto, (max-width: 890px) 100vw, 890px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside that operator, we decide to return a new array. The continent remains the same, and we filter the list of countries based on that continent:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"841\" height=\"147\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-5.png\" alt=\"\" class=\"wp-image-2014\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-5.png 841w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-5-300x52.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-5-768x134.png 768w\" sizes=\"auto, (max-width: 841px) 100vw, 841px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">FInally, we can use <code><a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/rxjs-tap-operator\/\" target=\"_blank\" rel=\"noopener\" title=\"\">tap<\/a><\/code> to run some side effects. In our case, we update the list of countries used by the dropdown, and we set the country dropdown value to the first country of that list to ensure that a country from a previous continent doesn&#8217;t remain selected:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"870\" height=\"173\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-6.png\" alt=\"\" class=\"wp-image-2015\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-6.png 870w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-6-300x60.png 300w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-6-768x153.png 768w\" sizes=\"auto, (max-width: 870px) 100vw, 870px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">And that&#8217;s it! You can see <a href=\"https:\/\/stackblitz.com\/edit\/at-rxjs-demo4?file=src%2Fapp%2Fapp.component.ts\" target=\"_blank\" rel=\"noopener\" title=\"\">that code in action on Stackblitz here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A few of you sent me their own solutions to the challenge, and a recurring theme was that most of you didn&#8217;t &#8220;connect&#8221; the Observables and just assumed that the list of countries would already be downloaded and available by the time the user selected a continent. Something along those lines, where <code>this.countries<\/code> would be received from the API before that code runs:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"560\" height=\"144\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-7.png\" alt=\"\" class=\"wp-image-2016\" style=\"width:661px;height:auto\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-7.png 560w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-7-300x77.png 300w\" sizes=\"auto, (max-width: 560px) 100vw, 560px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">While the above code would work most of the time, if a user selects a continent before <code>this.countries<\/code> is defined, an error would be thrown and the corresponding subscription destroyed, which means the above code would not run anymore when the user selects a new value. As a result, using operators is safer.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Another trick in my solution is that I didn&#8217;t use any <code>.subscribe<\/code> in my code, which means <a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/anti-pattern-series-not-unsubscribing-from-observables\/\" target=\"_blank\" rel=\"noopener\" title=\"\">I don&#8217;t have to unsubscribe, as I let the <code>async<\/code> pipe do so for me<\/a> automatically:<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"546\" height=\"161\" src=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-8.png\" alt=\"\" class=\"wp-image-2017\" srcset=\"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-8.png 546w, https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-8-300x88.png 300w\" sizes=\"auto, (max-width: 546px) 100vw, 546px\" \/><\/figure>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That&#8217;s it for code challenge #3! Next week, I&#8217;ll send you updates from <a href=\"https:\/\/ng-conf.org\/\" target=\"_blank\" rel=\"noopener\" title=\"\">ng-conf<\/a> in Salt Lake City. If you&#8217;re around, feel ree to come say hi!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Before I dive into the solution of code challenge #3, I wanted to mention that my next FREE workshop is scheduled for April 4th. It will be all about getting into RxJs from scratch, and you can register here. I&#8217;ll start from the basics and move on to more advanced topics, such as subjects and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,40,12,10],"tags":[],"class_list":["post-2009","post","type-post","status-publish","format-standard","hentry","category-angular","category-code-challenge","category-operators","category-rxjs"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"Before I dive into the solution of code challenge #3, I wanted to mention that my next FREE workshop is scheduled for April 4th. It will be all about getting into RxJs from scratch, and you can register here. I&#039;ll start from the basics and move on to more advanced topics, such as subjects and\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Alain Chautard\"\/>\n\t<meta name=\"google-site-verification\" content=\"SXxD3jwe28P5x4KWwWlYlHobuesNDkT6VWG1oVG1GcQ\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#article\",\"name\":\"Code challenge #3 solution | Angular Newsletter\",\"headline\":\"Code challenge #3 solution\",\"author\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/author\\\/alcfeoh\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/#organization\"},\"image\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/wp-content\\\/uploads\\\/2024\\\/03\\\/image-1.png\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#articleImage\",\"width\":382,\"height\":380},\"datePublished\":\"2024-03-13T05:00:00-07:00\",\"dateModified\":\"2024-03-12T14:57:23-07:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#webpage\"},\"articleSection\":\"Angular, Code Challenge, Operators, RxJs\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/#listItem\",\"name\":\"RxJs\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/#listItem\",\"position\":2,\"name\":\"RxJs\",\"item\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/operators\\\/#listItem\",\"name\":\"Operators\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/operators\\\/#listItem\",\"position\":3,\"name\":\"Operators\",\"item\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/operators\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#listItem\",\"name\":\"Code challenge #3 solution\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/#listItem\",\"name\":\"RxJs\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#listItem\",\"position\":4,\"name\":\"Code challenge #3 solution\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/category\\\/rxjs\\\/operators\\\/#listItem\",\"name\":\"Operators\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/#organization\",\"name\":\"Angular Training\",\"description\":\"Tutorials and updates about the Angular framework\",\"url\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/\",\"email\":\"contact@interstate21.com\",\"telephone\":\"+14089106087\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/wp-content\\\/uploads\\\/2018\\\/01\\\/blue-logo-vertical.png\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#organizationLogo\",\"width\":1234,\"height\":950},\"image\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#organizationLogo\"},\"sameAs\":[\"https:\\\/\\\/www.youtube.com\\\/@AngularTraining\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/achautard\\\/\",\"https:\\\/\\\/blog.angulartraining.com\\\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/author\\\/alcfeoh\\\/#author\",\"url\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/author\\\/alcfeoh\\\/\",\"name\":\"Alain Chautard\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/26ae8a75f090f33d4e79871307246008907228871b691f47cf15d2e7353939fd?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Alain Chautard\"},\"sameAs\":[\"https:\\\/\\\/twitter.com\\\/alainchautard\",\"https:\\\/\\\/www.youtube.com\\\/@AngularTraining\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/achautard\\\/\"]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#webpage\",\"url\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/\",\"name\":\"Code challenge #3 solution | Angular Newsletter\",\"description\":\"Before I dive into the solution of code challenge #3, I wanted to mention that my next FREE workshop is scheduled for April 4th. It will be all about getting into RxJs from scratch, and you can register here. I'll start from the basics and move on to more advanced topics, such as subjects and\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/code-challenge-3-solution\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/author\\\/alcfeoh\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/author\\\/alcfeoh\\\/#author\"},\"datePublished\":\"2024-03-13T05:00:00-07:00\",\"dateModified\":\"2024-03-12T14:57:23-07:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/#website\",\"url\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/\",\"name\":\"Angular Newsletter\",\"description\":\"Tutorials and updates about the Angular framework\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.angulartraining.com\\\/daily-newsletter\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Code challenge #3 solution | Angular Newsletter","description":"Before I dive into the solution of code challenge #3, I wanted to mention that my next FREE workshop is scheduled for April 4th. It will be all about getting into RxJs from scratch, and you can register here. I'll start from the basics and move on to more advanced topics, such as subjects and","canonical_url":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"google-site-verification":"SXxD3jwe28P5x4KWwWlYlHobuesNDkT6VWG1oVG1GcQ","miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#article","name":"Code challenge #3 solution | Angular Newsletter","headline":"Code challenge #3 solution","author":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/author\/alcfeoh\/#author"},"publisher":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/#organization"},"image":{"@type":"ImageObject","url":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2024\/03\/image-1.png","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#articleImage","width":382,"height":380},"datePublished":"2024-03-13T05:00:00-07:00","dateModified":"2024-03-12T14:57:23-07:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#webpage"},"isPartOf":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#webpage"},"articleSection":"Angular, Code Challenge, Operators, RxJs"},{"@type":"BreadcrumbList","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter#listItem","position":1,"name":"Home","item":"https:\/\/www.angulartraining.com\/daily-newsletter","nextItem":{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/#listItem","name":"RxJs"}},{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/#listItem","position":2,"name":"RxJs","item":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/operators\/#listItem","name":"Operators"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/operators\/#listItem","position":3,"name":"Operators","item":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/operators\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#listItem","name":"Code challenge #3 solution"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/#listItem","name":"RxJs"}},{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#listItem","position":4,"name":"Code challenge #3 solution","previousItem":{"@type":"ListItem","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/operators\/#listItem","name":"Operators"}}]},{"@type":"Organization","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/#organization","name":"Angular Training","description":"Tutorials and updates about the Angular framework","url":"https:\/\/www.angulartraining.com\/daily-newsletter\/","email":"contact@interstate21.com","telephone":"+14089106087","logo":{"@type":"ImageObject","url":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-content\/uploads\/2018\/01\/blue-logo-vertical.png","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#organizationLogo","width":1234,"height":950},"image":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#organizationLogo"},"sameAs":["https:\/\/www.youtube.com\/@AngularTraining","https:\/\/www.linkedin.com\/in\/achautard\/","https:\/\/blog.angulartraining.com\/"]},{"@type":"Person","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/author\/alcfeoh\/#author","url":"https:\/\/www.angulartraining.com\/daily-newsletter\/author\/alcfeoh\/","name":"Alain Chautard","image":{"@type":"ImageObject","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/26ae8a75f090f33d4e79871307246008907228871b691f47cf15d2e7353939fd?s=96&d=mm&r=g","width":96,"height":96,"caption":"Alain Chautard"},"sameAs":["https:\/\/twitter.com\/alainchautard","https:\/\/www.youtube.com\/@AngularTraining","https:\/\/www.linkedin.com\/in\/achautard\/"]},{"@type":"WebPage","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#webpage","url":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/","name":"Code challenge #3 solution | Angular Newsletter","description":"Before I dive into the solution of code challenge #3, I wanted to mention that my next FREE workshop is scheduled for April 4th. It will be all about getting into RxJs from scratch, and you can register here. I'll start from the basics and move on to more advanced topics, such as subjects and","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/#website"},"breadcrumb":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/#breadcrumblist"},"author":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/author\/alcfeoh\/#author"},"creator":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/author\/alcfeoh\/#author"},"datePublished":"2024-03-13T05:00:00-07:00","dateModified":"2024-03-12T14:57:23-07:00"},{"@type":"WebSite","@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/#website","url":"https:\/\/www.angulartraining.com\/daily-newsletter\/","name":"Angular Newsletter","description":"Tutorials and updates about the Angular framework","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.angulartraining.com\/daily-newsletter\/#organization"}}]}},"aioseo_meta_data":{"post_id":"2009","title":null,"description":null,"keywords":[],"keyphrases":{"focus":{"keyphrase":"","score":0,"analysis":{"keyphraseInTitle":{"score":0,"maxScore":9,"error":1}}},"additional":[]},"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":"","og_custom_url":null,"og_article_section":null,"og_article_tags":[],"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":"-1","robots_max_videopreview":"-1","robots_max_imagepreview":"large","priority":null,"frequency":"default","local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2024-03-12 21:21:07","updated":"2025-06-03 23:59:31","seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/\" title=\"RxJs\">RxJs<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/operators\/\" title=\"Operators\">Operators<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tCode challenge #3 solution\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.angulartraining.com\/daily-newsletter"},{"label":"RxJs","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/"},{"label":"Operators","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/category\/rxjs\/operators\/"},{"label":"Code challenge #3 solution","link":"https:\/\/www.angulartraining.com\/daily-newsletter\/code-challenge-3-solution\/"}],"_links":{"self":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2009","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/comments?post=2009"}],"version-history":[{"count":2,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2009\/revisions"}],"predecessor-version":[{"id":2019,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/posts\/2009\/revisions\/2019"}],"wp:attachment":[{"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/media?parent=2009"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/categories?post=2009"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.angulartraining.com\/daily-newsletter\/wp-json\/wp\/v2\/tags?post=2009"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}