{"id":1510942,"date":"2022-03-24T07:00:25","date_gmt":"2022-03-24T14:00:25","guid":{"rendered":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=1510942"},"modified":"2024-04-12T03:46:23","modified_gmt":"2024-04-12T10:46:23","slug":"introducing-the-new-routelayer","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer","title":{"rendered":"Introducing the new RouteLayer"},"author":7451,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"_searchwp_excluded":""},"categories":[738191],"tags":[96582,34541,27491,25111,764082],"industry":[],"product":[761642,36831,36601],"class_list":["post-1510942","blog","type-blog","status-publish","format-standard","hentry","category-developers","tag-arcgis-api-for-javascript","tag-directions","tag-jsapi4","tag-routing","tag-whats-new-march-2022","product-platform","product-js-api-arcgis","product-developers"],"acf":{"short_description":"RouteLayer is a new layer at version 4.23 of the ArcGIS API for JavaScript that provides routing analytics and route visualization.","flexible_content":[{"acf_fc_layout":"content","content":"<p>Some people prefer to take the route less travelled by, while others prefer the shortest route possible. Whatever path you choose, version 4.23 of the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/release-notes\/\" target=\"_blank\" rel=\"noopener\">ArcGIS API for JavaScript<\/a> has a routing solution for you.<\/p>\n<p>Prior to version 4.23, we had two ways to do routing: <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/sample-code\/route\/\" target=\"_blank\" rel=\"noopener\">route<\/a> (which replaced the deprecated RouteTask) and the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/sample-code\/widgets-directions\/\" target=\"_blank\" rel=\"noopener\">Directions widget<\/a>. The route module is great for low-level routing functions, where developers can configure the behavior in the app&#8217;s code. The Directions widget is ideal for quickly and easily adding a great routing experience to an app, with minimal coding.<\/p>\n<h2>The RouteLayer<\/h2>\n<p>Now we have another choice, the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-layers-RouteLayer.html\" target=\"_blank\" rel=\"noopener\">RouteLayer<\/a>. The RouteLayer is a layer for solving advanced routing problems. A solved route can be displayed on a map, and stored and retrieved from a portal, either as a route portal item, or as part of a webmap.<\/p>\n<p>A RouteLayer consists of two or more stops, and optionally, point, polygon, and polyline barriers. Results of a solved route are accessible from the\u00a0directionLines,\u00a0directionPoints, and\u00a0routeInfo\u00a0properties. Results include overall travel time, distance, and turn-by-turn directions.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":1513592,"id":1513592,"title":"Intro to RouteLayer","filename":"Screen-Shot-2022-03-16-at-10.39.22-AM.png","filesize":407907,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\/screen-shot-2022-03-16-at-10-39-22-am","alt":"Intro to RouteLayer","author":"7451","description":"Intro to RouteLayer","caption":"Introduction to RouteLayer sample with barriers. Click the image to explore.","name":"screen-shot-2022-03-16-at-10-39-22-am","status":"inherit","uploaded_to":1510942,"date":"2022-03-16 15:39:50","modified":"2022-03-21 19:59:26","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":2470,"height":1230,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM.png","medium-width":464,"medium-height":231,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM.png","medium_large-width":768,"medium_large-height":382,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM.png","large-width":1920,"large-height":956,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM-1536x765.png","1536x1536-width":1536,"1536x1536-height":765,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM-2048x1020.png","2048x2048-width":2048,"2048x2048-height":1020,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM-826x411.png","card_image-width":826,"card_image-height":411,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-10.39.22-AM-1920x956.png","wide_image-width":1920,"wide_image-height":956}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/developers.arcgis.com\/javascript\/latest\/sample-code\/layers-routelayer\/"},{"acf_fc_layout":"content","content":"<p>The above sample shows how to create and persist a RouteLayer containing stops, point barriers, a polygon barrier, and a polyline barrier. Because these are now dedicated classes in the API, creating a new RouteLayer is simple and straightforward. Skip to <a href=\"#classes-added\">the end<\/a> of this blog to see all the new routing classes we added at 4.23.<\/p>\n<p>Only geometries are required here, which we can handle manually if we already know them, or we could also use an existing layer to generate them. In this example, we&#8217;ll create everything manually to make it clearer.<\/p>\n<h2>Creating a new RouteLayer<\/h2>\n<p>Let&#8217;s look at the code below for creating a new RouteLayer.<\/p>\n"},{"acf_fc_layout":"content","content":"<pre><code style=\"display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; -webkit-text-size-adjust: none;\"><span style=\"color: #998; font-style: italic;\">\/\/ create new stops for start (Ontario) and end (Esri)<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> stops = [\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> Stop({\r\n    geometry: { x: -<span style=\"color: #008080;\">117.59275<\/span>, y: <span style=\"color: #008080;\">34.06200<\/span> },\r\n    name: <span style=\"color: #d14;\">\"Ontario Airport\"<\/span>\r\n  }),\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> Stop({\r\n    geometry: { x: -<span style=\"color: #008080;\">117.19570<\/span>, y: <span style=\"color: #008080;\">34.05609<\/span> },\r\n    name: <span style=\"color: #d14;\">\"Esri Campus\"<\/span>\r\n  }),\r\n];\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ create new point barriers<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> pointBarriers = [\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PointBarrier({ geometry: { x: -<span style=\"color: #008080;\">117.43576<\/span>, y: <span style=\"color: #008080;\">34.10264<\/span> } }),\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PointBarrier({ geometry: { x: -<span style=\"color: #008080;\">117.29412<\/span>, y: <span style=\"color: #008080;\">34.10530<\/span> } }),\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PointBarrier({ geometry: { x: -<span style=\"color: #008080;\">117.30507<\/span>, y: <span style=\"color: #008080;\">34.03644<\/span> } }),\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PointBarrier({ geometry: { x: -<span style=\"color: #008080;\">117.57527<\/span>, y: <span style=\"color: #008080;\">34.10282<\/span> } }),\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PointBarrier({ geometry: { x: -<span style=\"color: #008080;\">117.48886<\/span>, y: <span style=\"color: #008080;\">34.09552<\/span> } }),\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PointBarrier({ geometry: { x: -<span style=\"color: #008080;\">117.47636<\/span>, y: <span style=\"color: #008080;\">34.04798<\/span> } })\r\n];\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ create new polygon barrier<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> polygonBarriers = [\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PolygonBarrier({\r\n    geometry: {\r\n      rings: [[\r\n        [-<span style=\"color: #008080;\">117.49497<\/span> - <span style=\"color: #008080;\">0.01<\/span>, <span style=\"color: #008080;\">34.13484<\/span> - <span style=\"color: #008080;\">0.01<\/span>],\r\n        [-<span style=\"color: #008080;\">117.49497<\/span> - <span style=\"color: #008080;\">0.01<\/span>, <span style=\"color: #008080;\">34.13484<\/span> + <span style=\"color: #008080;\">0.01<\/span>],\r\n        [-<span style=\"color: #008080;\">117.49497<\/span> + <span style=\"color: #008080;\">0.01<\/span>, <span style=\"color: #008080;\">34.13484<\/span> + <span style=\"color: #008080;\">0.01<\/span>],\r\n        [-<span style=\"color: #008080;\">117.49497<\/span> + <span style=\"color: #008080;\">0.01<\/span>, <span style=\"color: #008080;\">34.13484<\/span> - <span style=\"color: #008080;\">0.01<\/span>],\r\n        [-<span style=\"color: #008080;\">117.49497<\/span> - <span style=\"color: #008080;\">0.01<\/span>, <span style=\"color: #008080;\">34.13484<\/span> - <span style=\"color: #008080;\">0.01<\/span>]\r\n      ]]\r\n    },\r\n    name: <span style=\"color: #d14;\">\"Street festival, Etiwanda\"<\/span>\r\n  })\r\n];\r\n<span style=\"color: #998; font-style: italic;\">\/\/ create new polyline barrier<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> polylineBarriers = [\r\n  <span style=\"color: #333; font-weight: bold;\">new<\/span> PolylineBarrier({\r\n    geometry: {\r\n      paths: [[\r\n        [-<span style=\"color: #008080;\">117.30584<\/span>, <span style=\"color: #008080;\">34.07115<\/span>],\r\n        [-<span style=\"color: #008080;\">117.26710<\/span>, <span style=\"color: #008080;\">34.04838<\/span>]\r\n      ]]\r\n    },\r\n    name: <span style=\"color: #d14;\">\"Major highway closure\"<\/span>\r\n  })\r\n];\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ create a new RouteLayer with stops and barriers<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> routeLayer = <span style=\"color: #333; font-weight: bold;\">new<\/span> RouteLayer({\r\n  stops,\r\n  pointBarriers,\r\n  polygonBarriers,\r\n  polylineBarriers\r\n});\r\n<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<p>We can see that creating a new RouteLayer is similar to creating any other layer with multiple properties. One caveat is that because this layer requires a call to a routing service to generate results, it&#8217;s best to use either <code>.then()<\/code> statements, or an asynchronous function for solving routes.<\/p>\n<p>Note that the start of the sample is: <code>(async () =&gt; {<\/code>. This means that the entire application will run asynchronously, which makes it easier to work with the results of a solved RouteLayer by using\u00a0<code>await<\/code> methods for resolved promises. Let&#8217;s look at how the above app handles that.<\/p>\n<pre><code style=\"display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; -webkit-text-size-adjust: none;\"><span style=\"color: #998; font-style: italic;\">\/\/ wait for the view and the RouteLayer to load<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">await<\/span> <span style=\"color: #0086b3;\">Promise<\/span>.all([view.when(), routeLayer.load()]);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ once the RouteLayer is loaded, solve the route<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ use the optional RouteParameters parameter to provide the apiKey<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ and other settings like directions language and travel mode<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> results = <span style=\"color: #333; font-weight: bold;\">await<\/span> routeLayer.solve({ apiKey });\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ the `solve()` method returns a routing solution<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ it contains the computed route, stops, and barriers<\/span>\r\nrouteLayer.update(results);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ <i>after the solved route has been applied to the layer\r\n\/\/ zoom to the route\u2019s extent<\/i><\/span>\r\n<span style=\"color: #333; font-weight: bold;\">await<\/span> view.goTo(routeLayer.routeInfo.geometry);\r\n<\/code><\/pre>\n<p>These <code>await<\/code> statements pause the code&#8217;s execution so that all relevant resources will be available. Now you may ask yourself, why doesn&#8217;t <code>RouteLayer.solve()<\/code> immediately update the layer? Why do we also have to call <code>RouteLayer.update()<\/code>?<\/p>\n<h2>Solving routes<\/h2>\n<p>When you have two or more stops, the RouteLayer can be solved. As explained above, this is a two step process. The route is solved based on information in the RouteLayer, and optionally, information in the RouteParameters.\u00a0 The <code>solve()<\/code> method returns a solution that can be queried, and applied to the layer if you want to view the results.<\/p>\n<p>However, before displaying the route, you may want to make some comparisons or calculations to ensure you are visualizing the optimal route for your app. For example, say you&#8217;re at the Esri Dev Summit, and you want a route to the nearest restaurant for dinner after a long day at the conference. So you add the convention center as the starting point, then add a variety of decent looking restaurants as end points. But, you only want to display the route to the closest restaurant.<\/p>\n<p>Which restaurant is closest? Easy, submit several solve() requests, and then only display the shortest route. Like this:<\/p>\n<pre><code style=\"display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; -webkit-text-size-adjust: none;\"><span style=\"color: #998; font-style: italic;\">\/\/ show me the routes to the nearest yummy restaurants<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ from the convention center<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> solutions = <span style=\"color: #333; font-weight: bold;\">await<\/span> <span style=\"color: #0086b3;\">Promise<\/span>.all([\r\n  routeLayer.solve({ stops: [convention, thaiFood] }),\r\n  routeLayer.solve({ stops: [convention, mexicanFood] }),\r\n  routeLayer.solve({ stops: [convention, italianFood] })\r\n]);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ now sort the results to find the shortest route<\/span>\r\nsolutions.sort((a, b) =&gt; a.routeInfo.totalDuration - b.routeInfo.totalDuration);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ once we have the shortest route, then update the RouteLayer<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ so we can see the route on the map<\/span>\r\nrouteLayer.update(solutions[<span style=\"color: #008080;\">0<\/span>]);\r\n<\/code><\/pre>\n<p>After you&#8217;ve updated the route, you can now save it for future use. If you&#8217;re curious about persistance, the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/sample-code\/layers-routelayer\/\" target=\"_blank\" rel=\"noopener\">RouteLayer sample<\/a> also demonstrates how to persist a solved RouteLayer as a route portal item, or as part of a webmap.<\/p>\n<h2>Persisting a RouteLayer<\/h2>\n<p>A unique feature of RouteLayer is that it has it&#8217;s own <code>save()<\/code> and <code>saveAs()<\/code> methods. This means that the RouteLayer can be persisted as a route portal item, so saved routes can be re-opened in apps like MapViewer or ArcGIS Navigator. Additionally, if added to a webmap, the RouteLayer will be automatically embedded when <code>WebMap.save()<\/code> or <code>WebMap.saveAs()<\/code> methods are used. The code for both options look very similar:<\/p>\n"},{"acf_fc_layout":"content","content":"<pre><code style=\"display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; -webkit-text-size-adjust: none;\"><span style=\"color: #998; font-style: italic;\">\/\/ save solved route as a route portal item<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> portalRouteItem = <span style=\"color: #333; font-weight: bold;\">await<\/span> routeLayer.saveAs({\r\n  title: <span style=\"color: #d14;\">\"Route from Ontario Airport to Esri Campus\"<\/span>,\r\n  snippet: <span style=\"color: #d14;\">\"Route created using the ArcGIS API for JavaScript\"<\/span>\r\n});\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ save solved route as part of a webmap<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> portalItem = <span style=\"color: #333; font-weight: bold;\">await<\/span> map.saveAs({\r\n  title: <span style=\"color: #d14;\">\"WebMap with route from Ontario Airport to Esri Campus\"<\/span>,\r\n  snippet: <span style=\"color: #d14;\">\"WebMap created using the ArcGIS API for JavaScript\"<\/span>\r\n});\r\n<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<p>Thus far we&#8217;ve been introduced to the new RouteLayer, seen how it works, and learned how to persist it&#8217;s results. Now let&#8217;s take things one stop further.<\/p>\n<h2>RouteLayer visualization<\/h2>\n<p>We haven&#8217;t discussed the visualization of RouteLayer yet. That&#8217;s because all the symbology we&#8217;ve seen has been defined by default in the API. While we have many plans for <a href=\"#road-ahead\">future enhancements<\/a> for the RouteLayer, we do have some options that we can use today. For example, we have support for both <code>blendMode<\/code> and <code>effect<\/code> properties. This means that we can enhance our visualizations to make more impressive looking routes.<\/p>\n<p>A great use case for this is when displaying two or more RouteLayers on a map. For example, say we wanted to make an app for people visiting the Esri office in Redlands, California. To welcome our guests, we pick some of our favorite spots in the area, and then provide walking and driving routes to their locations. Now we want to give precedence to walking routes, because walking is a healthier and (arguably) more fuel-efficient travel mode than driving. Open the <a href=\"https:\/\/noashx.github.io\/blog\/multiRouteLayers.html\" target=\"_blank\" rel=\"noopener\">Multi RouteLayer app<\/a> and click on a point of interest from the buttons in the top right.<\/p>\n"},{"acf_fc_layout":"image","image":{"ID":1514282,"id":1514282,"title":"Multi RouteLayer","filename":"Screen-Shot-2022-03-16-at-3.35.41-PM.png","filesize":187426,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\/screen-shot-2022-03-16-at-3-35-41-pm","alt":"Multi RouteLayer","author":"7451","description":"Multi RouteLayer","caption":"Routing app with multiple RouteLayers and multiple TravelModes. \nThe route is from work to ice cream.","name":"screen-shot-2022-03-16-at-3-35-41-pm","status":"inherit","uploaded_to":1510942,"date":"2022-03-16 20:36:09","modified":"2022-03-16 20:39:03","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":2524,"height":1040,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM.png","medium-width":464,"medium-height":191,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM.png","medium_large-width":768,"medium_large-height":316,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM.png","large-width":1920,"large-height":791,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM-1536x633.png","1536x1536-width":1536,"1536x1536-height":633,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM-2048x844.png","2048x2048-width":2048,"2048x2048-height":844,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM-826x340.png","card_image-width":826,"card_image-height":340,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/Screen-Shot-2022-03-16-at-3.35.41-PM-1920x791.png","wide_image-width":1920,"wide_image-height":791}},"image_position":"center","orientation":"horizontal","hyperlink":"https:\/\/noashx.github.io\/blog\/multiRouteLayers.html"},{"acf_fc_layout":"content","content":"<p>The code here looks similar to the sample app we looked at earlier, with two exceptions.<\/p>\n<p>First, we have to get all the information about our desired travel modes. To do this, we call the <a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-networkService.html#fetchServiceDescription\" target=\"_blank\" rel=\"noopener\">networkService.fetchServiceDescription()<\/a> method on our routing service to return available travel modes (amongst other information, like the service version). The previous app relied on the routing service&#8217;s default travel mode, but now we want to pick specific ones. You can learn more about travel modes in the <a href=\"https:\/\/doc.arcgis.com\/en\/arcgis-online\/reference\/travel-modes.htm\" target=\"_blank\" rel=\"noopener\">Configure travel modes<\/a> documentation.<\/p>\n<p>Second, we apply a <code>bloom<\/code> effect on our second RouteLayer to accentuate the layer. We do this because we want to encourage people to walk when possible and practical.<\/p>\n<p>Note that both RouteLayers have the same start and end, but take (mostly) different routes and are visualized differently.<\/p>\n<pre><code style=\"display: block; overflow-x: auto; padding: 0.5em; color: #333; background: #f8f8f8; -webkit-text-size-adjust: none;\"><span style=\"color: #998; font-style: italic;\">\/\/ the routing service URL<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> url = <span style=\"color: #d14;\">\"ROUTING_SERVICE_URL\"<\/span>;\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ API key from developer's account<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ https:\/\/developers.arcgis.com\/documentation\/mapping-apis-and-services\/security\/api-keys\/<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> apiKey = <span style=\"color: #d14;\">\"YOUR_API_KEY\"<\/span>;\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ get the information about our routing service<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> {supportedTravelModes} = <span style=\"color: #333; font-weight: bold;\">await<\/span> networkService.fetchServiceDescription(url, apiKey);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ get the travel mode details for \"Driving Time\"<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> driveTravelMode = supportedTravelModes.find((travelMode) =&gt; \r\n  travelMode.name === <span style=\"color: #d14;\">\"Driving Time\"<\/span>);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ get the travel mode details for \"Walking Time\"<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> walkTravelMode = supportedTravelModes.find((travelMode) =&gt; \r\n  travelMode.name === <span style=\"color: #d14;\">\"Walking Time\"<\/span>);\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ create a RouteLayer for \"Driving Time\"<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> drive = <span style=\"color: #333; font-weight: bold;\">new<\/span> RouteLayer({\r\n  stops: [\r\n    { geometry: esri },\r\n    { geometry: destination }\r\n  ]\r\n});\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ Solve and update route for \"Driving Time\"<\/span>\r\n<span style=\"color: #998; font-style: italic;\">\/\/ and zoom to results<\/span>\r\ndrive.solve({ apiKey, travelMode: driveTravelMode }).then((results) =&gt; {\r\n  drive.update(results);\r\n  <span style=\"color: #333; font-weight: bold;\">const<\/span> extent = results.routeInfo.geometry.extent.clone();\r\n  view.goTo(extent.expand(<span style=\"color: #008080;\">1.5<\/span>));\r\n});\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ create another RouteLayer for \"Walking Time\" with bloom<\/span>\r\n<span style=\"color: #333; font-weight: bold;\">const<\/span> walk = <span style=\"color: #333; font-weight: bold;\">new<\/span> RouteLayer({\r\n  stops: [\r\n    { geometry: esri },\r\n    { geometry: destination }\r\n  ],\r\n  effect: <span style=\"color: #d14;\">\"bloom(2, 0.5px, 0)\"<\/span>\r\n});\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ Solve and update route \"Walking Time\"<\/span>\r\nwalk.solve({ apiKey, travelMode: walkTravelMode }).then((results) =&gt; {\r\n  walk.update(results);\r\n});\r\n\r\n<span style=\"color: #998; font-style: italic;\">\/\/ add both RouteLayers to the map<\/span>\r\nmap.addMany([drive, walk]);\r\n<\/code><\/pre>\n"},{"acf_fc_layout":"content","content":"<p><a name=\"road-ahead\"><\/a><\/p>\n<h2>The road ahead for RouteLayer<\/h2>\n<p>We hope you&#8217;ve enjoyed learning about the new RouteLayer, and all it&#8217;s exciting capabilities. But this is just the beginning of our journey. We have some known limitations that we are working hard on addressing, such as adding more visualization options, and support for labeling, popups, and 3D SceneViews (currently RouteLayer only works in 2D MapViews).<\/p>\n<p>We are also thinking about the layer&#8217;s behavior, and it&#8217;s ability to update stops and waypoints with drag and drop, or on-click events.<\/p>\n<p>We&#8217;d love to hear your feedback about the new RouteLayer, and how future enhancements could help with your routing workflows. Leave us a comment below!<\/p>\n"},{"acf_fc_layout":"content","content":"<p><a name=\"classes-added\"><\/a><\/p>\n<h2>References<\/h2>\n<p>Classes added at 4.23, for your routing convenience:<\/p>\n<p><strong>DirectionLine<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-DirectionLine.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-DirectionLine.html<\/a><\/p>\n<p><strong>DirectionPoint<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-DirectionPoint.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-DirectionPoint.html<\/a><\/p>\n<p><strong>PointBarrier<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-PointBarrier.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-PointBarrier.html<\/a><\/p>\n<p><strong>PolygonBarrier<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-PolygonBarrier.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-PolygonBarrier.html<\/a><\/p>\n<p><strong>PolylineBarrier<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-PolylineBarrier.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-PolylineBarrier.html<\/a><\/p>\n<p><strong>RouteInfo<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-RouteInfo.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-RouteInfo.html<\/a><\/p>\n<p><strong>RouteLayer<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-layers-RouteLayer.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-layers-RouteLayer.html<\/a><\/p>\n<p><strong>RouteSolveResult<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-RouteSolveResult.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-RouteSolveResult.html<\/a><\/p>\n<p><strong>Stop<\/strong><\/p>\n<p><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-Stop.html\" target=\"_blank\" rel=\"noopener\">https:\/\/developers.arcgis.com\/javascript\/latest\/api-reference\/esri-rest-support-Stop.html<\/a><\/p>\n<p>Thank you for reading until the end of this blog! Stay tuned for more routing developments in the future.<\/p>\n"}],"authors":[{"ID":7451,"user_firstname":"Noah","user_lastname":"Sager","nickname":"Noah Sager","user_nicename":"noah-sager","display_name":"Noah Sager","user_email":"NSager@esri.com","user_url":"https:\/\/www.noahsager.net\/","user_registered":"2018-03-21 18:21:19","user_description":"Passionate about JavaScript, maps, and writing (not necessarily in that order). Big fan of squirrels. Journeyman mapper of Utility Lines and Public Restrooms. Product Engineer on the ArcGIS API for JavaScript team. In Noah\u2019s spare time, he also enjoys parenting.","user_avatar":"<img alt='' src='https:\/\/secure.gravatar.com\/avatar\/6807cdccf3ddd5b30b84cdf9368ce6736c3d0ff9bd0a09c1f5efc03253069b64?s=96&#038;d=blank&#038;r=g' srcset='https:\/\/secure.gravatar.com\/avatar\/6807cdccf3ddd5b30b84cdf9368ce6736c3d0ff9bd0a09c1f5efc03253069b64?s=192&#038;d=blank&#038;r=g 2x' class='avatar avatar-96 photo' height='96' width='96' loading='lazy' decoding='async'\/>"}],"related_articles":"","card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/RL_blog_card.png","wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/RouteTheWorld.png"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Introducing the new RouteLayer<\/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.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Introducing the new RouteLayer\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\" \/>\n<meta property=\"og:site_name\" content=\"ArcGIS Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/esrigis\/\" \/>\n<meta property=\"article:modified_time\" content=\"2024-04-12T10:46:23+00:00\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@ESRI\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\"},\"author\":{\"name\":\"Noah Sager\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/31358cd525c152696fcd5fe96f49e068\"},\"headline\":\"Introducing the new RouteLayer\",\"datePublished\":\"2022-03-24T14:00:25+00:00\",\"dateModified\":\"2024-04-12T10:46:23+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\"},\"wordCount\":4,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"keywords\":[\"ArcGIS API for JavaScript\",\"Directions\",\"jsapi4\",\"Routing\",\"whats new march 2022\"],\"articleSection\":[\"Developers\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\",\"name\":\"Introducing the new RouteLayer\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\"},\"datePublished\":\"2022-03-24T14:00:25+00:00\",\"dateModified\":\"2024-04-12T10:46:23+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/arcgis-blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Introducing the new RouteLayer\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"name\":\"ArcGIS Blog\",\"description\":\"Get insider info from Esri product teams\",\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\",\"name\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"width\":400,\"height\":400,\"caption\":\"Esri\"},\"image\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/esrigis\/\",\"https:\/\/x.com\/ESRI\",\"https:\/\/www.linkedin.com\/company\/5311\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/31358cd525c152696fcd5fe96f49e068\",\"name\":\"Noah Sager\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/6807cdccf3ddd5b30b84cdf9368ce6736c3d0ff9bd0a09c1f5efc03253069b64?s=96&d=blank&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/6807cdccf3ddd5b30b84cdf9368ce6736c3d0ff9bd0a09c1f5efc03253069b64?s=96&d=blank&r=g\",\"caption\":\"Noah Sager\"},\"description\":\"Passionate about JavaScript, maps, and writing (not necessarily in that order). Big fan of squirrels. Journeyman mapper of Utility Lines and Public Restrooms. Product Engineer on the ArcGIS API for JavaScript team. In Noah\u2019s spare time, he also enjoys parenting.\",\"sameAs\":[\"https:\/\/www.noahsager.net\/\",\"https:\/\/www.linkedin.com\/in\/noah-sager\",\"https:\/\/x.com\/noashx\"],\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/author\/noah-sager\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Introducing the new RouteLayer","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.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer","og_locale":"en_US","og_type":"article","og_title":"Introducing the new RouteLayer","og_url":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer","og_site_name":"ArcGIS Blog","article_publisher":"https:\/\/www.facebook.com\/esrigis\/","article_modified_time":"2024-04-12T10:46:23+00:00","twitter_card":"summary_large_image","twitter_site":"@ESRI","schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#article","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer"},"author":{"name":"Noah Sager","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/31358cd525c152696fcd5fe96f49e068"},"headline":"Introducing the new RouteLayer","datePublished":"2022-03-24T14:00:25+00:00","dateModified":"2024-04-12T10:46:23+00:00","mainEntityOfPage":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer"},"wordCount":4,"commentCount":2,"publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"keywords":["ArcGIS API for JavaScript","Directions","jsapi4","Routing","whats new march 2022"],"articleSection":["Developers"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer","url":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer","name":"Introducing the new RouteLayer","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#website"},"datePublished":"2022-03-24T14:00:25+00:00","dateModified":"2024-04-12T10:46:23+00:00","breadcrumb":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/developers\/introducing-the-new-routelayer#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/arcgis-blog\/"},{"@type":"ListItem","position":2,"name":"Introducing the new RouteLayer"}]},{"@type":"WebSite","@id":"https:\/\/www.esri.com\/arcgis-blog\/#website","url":"https:\/\/www.esri.com\/arcgis-blog\/","name":"ArcGIS Blog","description":"Get insider info from Esri product teams","publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization","name":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","width":400,"height":400,"caption":"Esri"},"image":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/esrigis\/","https:\/\/x.com\/ESRI","https:\/\/www.linkedin.com\/company\/5311\/"]},{"@type":"Person","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/31358cd525c152696fcd5fe96f49e068","name":"Noah Sager","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/6807cdccf3ddd5b30b84cdf9368ce6736c3d0ff9bd0a09c1f5efc03253069b64?s=96&d=blank&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6807cdccf3ddd5b30b84cdf9368ce6736c3d0ff9bd0a09c1f5efc03253069b64?s=96&d=blank&r=g","caption":"Noah Sager"},"description":"Passionate about JavaScript, maps, and writing (not necessarily in that order). Big fan of squirrels. Journeyman mapper of Utility Lines and Public Restrooms. Product Engineer on the ArcGIS API for JavaScript team. In Noah\u2019s spare time, he also enjoys parenting.","sameAs":["https:\/\/www.noahsager.net\/","https:\/\/www.linkedin.com\/in\/noah-sager","https:\/\/x.com\/noashx"],"url":"https:\/\/www.esri.com\/arcgis-blog\/author\/noah-sager"}]}},"text_date":"March 24, 2022","author_name":"Noah Sager","author_page":"https:\/\/www.esri.com\/arcgis-blog\/author\/noah-sager","custom_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2022\/03\/RouteTheWorld.png","primary_product":"ArcGIS Maps SDK for JavaScript","tag_data":[{"term_id":96582,"name":"ArcGIS API for JavaScript","slug":"arcgis-api-for-javascript","term_group":0,"term_taxonomy_id":96582,"taxonomy":"post_tag","description":"","parent":0,"count":58,"filter":"raw"},{"term_id":34541,"name":"Directions","slug":"directions","term_group":0,"term_taxonomy_id":34541,"taxonomy":"post_tag","description":"","parent":0,"count":6,"filter":"raw"},{"term_id":27491,"name":"jsapi4","slug":"jsapi4","term_group":0,"term_taxonomy_id":27491,"taxonomy":"post_tag","description":"","parent":0,"count":111,"filter":"raw"},{"term_id":25111,"name":"Routing","slug":"routing","term_group":0,"term_taxonomy_id":25111,"taxonomy":"post_tag","description":"","parent":0,"count":16,"filter":"raw"},{"term_id":764082,"name":"whats new march 2022","slug":"whats-new-march-2022","term_group":0,"term_taxonomy_id":764082,"taxonomy":"post_tag","description":"","parent":0,"count":27,"filter":"raw"}],"category_data":[{"term_id":738191,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":738191,"taxonomy":"category","description":"","parent":0,"count":421,"filter":"raw"}],"product_data":[{"term_id":761642,"name":"ArcGIS Location Platform","slug":"platform","term_group":0,"term_taxonomy_id":761642,"taxonomy":"product","description":"","parent":36601,"count":213,"filter":"raw"},{"term_id":36831,"name":"ArcGIS Maps SDK for JavaScript","slug":"js-api-arcgis","term_group":0,"term_taxonomy_id":36831,"taxonomy":"product","description":"","parent":36601,"count":362,"filter":"raw"},{"term_id":36601,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":36601,"taxonomy":"product","description":"","parent":0,"count":763,"filter":"raw"}],"primary_product_link":"https:\/\/www.esri.com\/arcgis-blog\/?s=#&products=js-api-arcgis","_links":{"self":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/1510942","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/users\/7451"}],"replies":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/comments?post=1510942"}],"version-history":[{"count":0,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/1510942\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/media?parent=1510942"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/categories?post=1510942"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/tags?post=1510942"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/industry?post=1510942"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/product?post=1510942"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}