<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Angular &#8211; Pauls Blog</title>
	<atom:link href="https://sterl.org/category/angular/feed/" rel="self" type="application/rss+xml" />
	<link>https://sterl.org</link>
	<description></description>
	<lastBuildDate>Wed, 24 May 2023 14:01:20 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Angular configure user browser locale</title>
		<link>https://sterl.org/2023/01/angular-configure-user-browser-locale/</link>
					<comments>https://sterl.org/2023/01/angular-configure-user-browser-locale/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sat, 21 Jan 2023 12:54:35 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<category><![CDATA[date pipe]]></category>
		<category><![CDATA[DatePipe]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[locale]]></category>
		<category><![CDATA[LOCALE_ID]]></category>
		<guid isPermaLink="false">https://sterl.org/?p=853</guid>

					<description><![CDATA[Problem Using the angular date pipe etc. we often see that by default the format is en-US instead of the expected browser language of the user. Solution What we have to do is quite simple:]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>Using the angular date pipe etc. we often see that by default the format is <code>en-US</code> instead of the expected browser language of the user.</p>



<h2 class="wp-block-heading">Solution</h2>



<p>What we have to do is quite simple:</p>



<ol class="wp-block-list">
<li>Import the locales we want to support</li>



<li>Register the locales</li>



<li>Configure <code>LOCALE_ID</code> <code>provider</code> using the browser language</li>
</ol>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/typescript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;TypeScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;typescript&quot;}">import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

// 1. Import the locales we want to support, here we import just two
import localeDe from '@angular/common/locales/de';
import localeEn from '@angular/common/locales/en';
import { LOCALE_ID } from '@angular/core';
import { registerLocaleData } from '@angular/common';

// other imports ...

@NgModule({
  declarations: [
    AppComponent,
  ],
  imports: [
    BrowserModule,
    FormsModule,
	// other imports ...
  ],
  providers: [
    // 3. Configure LOCALE_ID provider using the browser language
    {provide: LOCALE_ID, useValue: navigator.language ?? 'en' }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {
  constructor() {
    // 2. Register the locales
    registerLocaleData(localeDe, 'de');
    registerLocaleData(localeEn, 'en');
  }
 }
</pre></div>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2023/01/angular-configure-user-browser-locale/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Angular &#038; Spring Boot</title>
		<link>https://sterl.org/2019/02/angular-spring-boot/</link>
					<comments>https://sterl.org/2019/02/angular-spring-boot/#respond</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Sun, 17 Feb 2019 08:47:14 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Spring Boot]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[Angular Spring]]></category>
		<category><![CDATA[Angular Spring Boot]]></category>
		<category><![CDATA[HTML 5]]></category>
		<category><![CDATA[HTML5]]></category>
		<category><![CDATA[Spring]]></category>
		<guid isPermaLink="false">http://sterl.org/?p=274</guid>

					<description><![CDATA[Problem We want to combine Spring and Angular use the Angular developing features but also be able to use the Spring IDE, in the end, everything should be build using maven and nicely packed into a JAR.Let&#8217;s get started. Overview Less text more code get me to the source. Multi-Module project It may make sense&#8230;]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">Problem</h2>



<p>We want to combine Spring and  Angular use the Angular developing features but also be able to use the Spring IDE, in the end, everything should be build using maven and nicely packed into a JAR.<br>Let&#8217;s get started.</p>



<h2 class="wp-block-heading">Overview</h2>



<ul class="wp-block-list">
<li>Create a multi-module project</li>



<li>Pack the frontend into an own JAR</li>



<li>Include the frontend JAR into the Spring application</li>



<li>Add a caching configuration</li>
</ul>



<p><a href="https://github.com/sterlp/spring-angular-starter">Less text more code get me to the source.</a></p>



<h2 class="wp-block-heading"> Multi-Module project </h2>



<ul class="wp-block-list">
<li>Create a new simple Spring project using <a href="https://start.spring.io/">https://start.spring.io/</a></li>



<li>Generate a new angular project <code>ng new frontend</code></li>



<li>Create a new pom and include frontend and backend </li>
</ul>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">&lt;modules&gt;
  &lt;module&gt;frontend&lt;/module&gt; 
  &lt;module&gt;backend&lt;/module&gt; 
&lt;/modules&gt;</pre></div>



<p>

It may make sense to move the spring parent into the <a href="https://github.com/sterlp/spring-angular-starter/blob/master/pom.xml#L6">root-pom</a>.

</p>



<figure class="wp-block-image"><img fetchpriority="high" decoding="async" width="494" height="110" src="http://sterl.org/wp-content/uploads/2019/02/angular-spring-project-structur.png" alt="" class="wp-image-276" srcset="https://sterl.org/wp-content/uploads/2019/02/angular-spring-project-structur.png 494w, https://sterl.org/wp-content/uploads/2019/02/angular-spring-project-structur-300x67.png 300w" sizes="(max-width: 494px) 100vw, 494px" /></figure>



<h3 class="wp-block-heading">Why a multi-module?</h3>



<p>You might think why the hack we don&#8217;t just pull everything into one maven artifact? Well, separation both may be considered good practice but the real reason is: <br>We can in that way use, during the development, the best tools for the job. Means use the angular dev server for the front-end and the Spring STS IDE for the backend. Means also just restart/ reload the UI or the Backend if the change that. Even more, build the UI and use the backend running somewhere else.</p>



<h3 class="wp-block-heading">Build angular with maven</h3>



<p>Overall we have here to choose, either we use the <a rel="noreferrer noopener" aria-label="frontend-maven-plugin (öffnet in neuem Tab)" href="https://github.com/eirslett/frontend-maven-plugin" target="_blank">frontend-maven-plugin</a>, assuming the CI server has no nodeJS installed or we go with the <a rel="noreferrer noopener" aria-label="exec-maven-plugin (öffnet in neuem Tab)" href="https://www.mojohaus.org/exec-maven-plugin/" target="_blank">exec-maven-plugin</a>. The last one is faster assuming the CI server has not to pull nodeJS first. What we want to run is:</p>



<ul class="wp-block-list">
<li><g class="gr_ gr_3 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling" id="3" data-gr-id="3">npm</g> install</li>



<li>ng build &#8211;prod</li>
</ul>



<h4 class="wp-block-heading">Build angular with exec-maven-plugin</h4>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;xml&quot;,&quot;mime&quot;:&quot;application/xml&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;XML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;xml&quot;}">&lt;plugin&gt;
    &lt;artifactId&gt;exec-maven-plugin&lt;/artifactId&gt;
    &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;id&gt;npm install&lt;/id&gt;
            &lt;goals&gt;
                &lt;goal&gt;exec&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;phase&gt;generate-resources&lt;/phase&gt;
            &lt;configuration&gt;
                &lt;executable&gt;npm&lt;/executable&gt;
                &lt;arguments&gt;
                    &lt;argument&gt;install&lt;/argument&gt;
                &lt;/arguments&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;

        &lt;execution&gt;
            &lt;id&gt;angular-cli build&lt;/id&gt;
            &lt;goals&gt;
                &lt;goal&gt;exec&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;phase&gt;compile&lt;/phase&gt;
            &lt;configuration&gt;
                &lt;executable&gt;ng&lt;/executable&gt;
                &lt;arguments&gt;
                    &lt;argument&gt;build&lt;/argument&gt;
                  	&lt;!-- only neded in old versions --&gt;
                    &lt;!-- &lt;argument&gt;--prod&lt;/argument&gt; --&gt;
                    &lt;argument&gt;--output-path&lt;/argument&gt;
                    &lt;argument&gt;${project.build.outputDirectory}/META-INF/resources/webjars/${project.artifactId}/${project.version}&lt;/argument&gt;
                &lt;/arguments&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;</pre></div>



<p>This will not delete the <code>node_modules</code> folder; which is intended. As this takes usually some unnecessary time.</p>



<div class="bs-callout bs-callout-info"><strong>Note:</strong>
We added here already the <code>--output-path</code> to emulate a kind of web-jar, we will use this later to configure the Spring resource handler. We could of course remove the version here.
</div>



<h4 class="wp-block-heading">Add node_modules to mvn clean</h4>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;plugin&gt;
	&lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
	&lt;artifactId&gt;maven-clean-plugin&lt;/artifactId&gt;
	&lt;configuration&gt;
		&lt;filesets&gt;
			&lt;fileset&gt;
				&lt;directory&gt;node_modules&lt;/directory&gt;
			&lt;/fileset&gt;
		&lt;/filesets&gt;
	&lt;/configuration&gt;
&lt;/plugin&gt;</pre></div>



<h3 class="wp-block-heading">Include the Angular frontend in Spring</h3>



<p>Again we have two ways to go, we could either include the JAR file and configure the resource handler, or just copy the files over into the static folder of spring during the build. The last one is very easy the first one has the advantage that we could include easily multiple angular JARs into our project.</p>



<h4 class="wp-block-heading">Include the frontend as JAR</h4>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;dependency&gt;
    &lt;groupId&gt;${project.groupId}&lt;/groupId&gt;
    &lt;artifactId&gt;frontend&lt;/artifactId&gt;
    &lt;version&gt;${project.version}&lt;/version&gt;
&lt;/dependency&gt;</pre></div>



<p>In your Spring application add <code>implements WebMvcConfigurer</code>. This will allow you to extend</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@Autowired private BuildProperties buildProperties;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    final String jarResourcePath = &quot;classpath:/META-INF/resources/webjars/frontend/&quot; + buildProperties.getVersion() + &quot;/&quot;;
        // no caching for HTML pages
        registry.addResourceHandler(&quot;/ui/*.html&quot;)
                .setCacheControl(CacheControl.noStore().sMaxAge(0, TimeUnit.SECONDS).mustRevalidate())
                .setCachePeriod(0)
                .addResourceLocations(jarResourcePath);

        // 365 days for JS and CSS files, which have a hash code in the file name 
        // generated by angular
        registry.addResourceHandler(&quot;/ui/*.js&quot;, &quot;/ui/*.css&quot;)
                .addResourceLocations(jarResourcePath)
                .setCacheControl(CacheControl.maxAge(365, TimeUnit.DAYS))
                .resourceChain(true);
        
        // apply custom config as needed to the remaining resources
        registry.addResourceHandler(&quot;/ui/**&quot;)
                .addResourceLocations(jarResourcePath)
                .setCacheControl(CacheControl.maxAge(7, TimeUnit.DAYS))
                .resourceChain(true);
	
}</pre></div>



<div class="bs-callout bs-callout-info"><strong>Note:</strong>
We added here already a caching configuration.
</div>



<p>In addition we have to tell Spring that by default if anybody opens <code>/</code> we want to display the <code>index.html</code>. This is only needed if we include the angular app as JAR, as we can just delete the <code>static</code> folder.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController(&quot;/&quot;).setViewName(&quot;forward:/index.html&quot;);
}

// in the addResourceHandlers we can also alternatively add the view ot the base e.g. 
// / or ui/
// handy in case of PathLocationStrategy
registry.addResourceHandler(&quot;/&quot;)
    .setCacheControl(CacheControl.noStore().sMaxAge(0, TimeUnit.SECONDS).mustRevalidate()).setCachePeriod(0)
    .addResourceLocations(jarResourcePath + &quot;index.html&quot;);</pre></div>



<h4 class="wp-block-heading">Copy the Angular files</h4>



<p>The most simple way to just include the angular into the build JAR is to copy them during the package phase into the static directory from Spring. From where it will just behave like a regular application.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;htmlmixed&quot;,&quot;mime&quot;:&quot;text/html&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;HTML&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;html&quot;}">&lt;plugin&gt;
    &lt;artifactId&gt;maven-resources-plugin&lt;/artifactId&gt;
    &lt;executions&gt;
        &lt;execution&gt;
            &lt;id&gt;copy frontend resources&lt;/id&gt;
            &lt;phase&gt;prepare-package&lt;/phase&gt;
            &lt;goals&gt;
                &lt;goal&gt;copy-resources&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
                &lt;outputDirectory&gt;${project.build.outputDirectory}/static&lt;/outputDirectory&gt;
                &lt;resources&gt;
                    &lt;resource&gt;
                        &lt;directory&gt;../frontend/target/classes/META-INF/resources/webjars/frontend/${project.version}&lt;/directory&gt;
                    &lt;/resource&gt;
                &lt;/resources&gt;
            &lt;/configuration&gt;
        &lt;/execution&gt;
    &lt;/executions&gt;
&lt;/plugin&gt;</pre></div>



<p>If we copy the resources, we can just set <code>optional</code> onto the frontend JAR or <code>provided</code>. The only reason we keep it in the <code>pom.xml</code> is just to ensure that it gets build first by maven; even if somebody re-sorts the modules in the root pom.</p>



<div class="bs-callout bs-callout-info"><strong>Note:</strong>
If we copy the resources we can also remove the <code>addResourceHandlers</code> configuration from the app. As we don&#8217;t need to tell Spring to check the JAR file too.
</div>



<h3 class="wp-block-heading">Handling HTML 5 routes in Spring</h3>



<h4 class="wp-block-heading">Using a Regex (not recommended)</h4>



<p>A common problem is to handle any HTML5 routes from angular, if why are directly opened in the browser. We don&#8217;t really want to add a view handler for each angular route. We have just to add a simple <code>@Controller</code> with the following code.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@RequestMapping(value = &quot;/{[path:[^\\.]*}&quot;)
public String redirect() {
    return &quot;forward:/index.html&quot;;
}</pre></div>



<h4 class="wp-block-heading">Using a fallback route</h4>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">registry.addResourceHandler(&quot;/**&quot;).addResourceLocations(jarResourcePath)
        .setCacheControl(CacheControl.maxAge(1, TimeUnit.HOURS)).resourceChain(true)
        .addResolver(new PathResourceResolver() {
            // fall back to our index.html for any other stuff
            // to support angular PathLocationStrategy
            @Override
            protected Resource getResource(String resourcePath, Resource location) throws IOException {
                final Resource requestedResource = location.createRelative(resourcePath);
                Resource result = requestedResource;
                if (!requestedResource.exists()) {
                    result = new ClassPathResource(&quot;/META-INF/resources/index.html&quot;);
                }
                return result;
            }
        });</pre></div>



<h4 class="wp-block-heading">Custom UI base path</h4>



<p>Another solution would be to publish the API and the UI with different prefixes e.g.:</p>



<ul class="wp-block-list">
<li><strong>/api/*</strong> or <strong>/rest/*</strong> for all REST services</li>



<li><strong>/ui/*</strong> for the angular UI</li>
</ul>



<p>This makes the controller match clearer and more predictable if also other services like the Swagger UI etc. are hosted too. But it requires some adjustments too:</p>



<ul class="wp-block-list">
<li>base href for the HTML5 angular navigation has to be set <code>--base-href /ui/</code></li>



<li>The resource handler above need have <strong>/ui/*</strong> prefix</li>



<li>We need a filter or a controller</li>
</ul>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">// custom filter, which does the same as the controller
@Bean
public OncePerRequestFilter angularForwardFilter() {
    return new OncePerRequestFilter() {
        @Override
        protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
            final String requestURI = request.getRequestURI();
            if (requestURI.startsWith(&quot;/ui&quot;) &amp;&amp; !requestURI.endsWith(&quot;/ui/index.html&quot;) &amp;&amp; !requestURI.contains(&quot;.&quot;)) {
                request.getRequestDispatcher(&quot;/ui/index.html&quot;).forward(request, response);
            } else {
                filterChain.doFilter(request, response);
            }
        }
    };
}
// custom controller class with a regex instead of the OncePerRequestFilter
@Controller
@RequestMapping(&quot;/ui&quot;)
public class AngularUiController {
    @GetMapping(&quot;{[path:[^\\.]*}&quot;)
    String index() {
        return &quot;forward:/ui/index.html&quot;;
    }
}</pre></div>



<h4 class="wp-block-heading">Explicit match</h4>



<p>Last but not least we can, of course, duplicate any angular route in our request mapping.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text/x-java&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Java&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;java&quot;}">@RequestMapping({&quot;/&quot;, &quot;/home&quot;, &quot;/home/*&quot;, &quot;/person&quot;, &quot;/person/list&quot;})
public String redirect() {
    return &quot;forward:/index.html&quot;;
}</pre></div>



<h2 class="wp-block-heading">Avoid reloading the backend on frontend changes</h2>



<p>Including the dev-tools from Spring will unfortunately also reload the backend if we change the frontend. We could of course just remove the frontend JAR dependency but we could also tell Spring to stop. For this we have to create the <a rel="noreferrer noopener" aria-label="spring-devtools.properties (öffnet in neuem Tab)" href="https://github.com/sterlp/spring-angular-starter/blob/master/backend/src/main/resources/META-INF/spring-devtools.properties" target="_blank">spring-<g class="gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling" id="7" data-gr-id="7">devtools</g>.properties</a> in the <code>META-INF</code> directory telling Spring not to do so:</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;properties&quot;,&quot;mime&quot;:&quot;text/x-properties&quot;,&quot;theme&quot;:&quot;bespin&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;Properties files&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;properties&quot;}">restart.exclude.frontend=.*/frontend/.*</pre></div>



<h2 class="wp-block-heading">Proxy /<g class="gr_ gr_77 gr-alert gr_spell gr_inline_cards gr_run_anim ContextualSpelling ins-del multiReplace" id="77" data-gr-id="77">api</g> calls to the backend</h2>



<p>Now we have to forward any calls going to <code>/api</code> to our backend otherwise we cannot get any data from any REST call during the usage of the angular dev web-server. For that, we have to add the <a href="https://github.com/sterlp/spring-angular-starter/blob/master/frontend/proxy.conf.json" target="_blank" rel="noreferrer noopener" aria-label="proxy.conf.json (öffnet in neuem Tab)">proxy.conf.json</a> to the project</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
    &quot;/api&quot;: {
        &quot;target&quot;: &quot;http://localhost:8080&quot;,
        &quot;secure&quot;: false
    }
}</pre></div>



<p>and extend <code>package.json</code> to add a short cut add the proxy config if we run <code>ng serve</code>.</p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/json&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JSON&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;json&quot;}">{
  &quot;scripts&quot;: {
    &quot;start&quot;: &quot;ng serve --proxy-config proxy.conf.json&quot;,</pre></div>



<p>Now we can run the Angular dev server with the proxy config using <code>npm start</code>.</p>



<h2 class="wp-block-heading">Links</h2>



<ul class="wp-block-list">
<li><a href="https://github.com/sterlp/spring-angular-starter">https://github.com/sterlp/spring-angular-starter</a></li>



<li><a href="https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii#using-ldquo-natural-rdquo-routes" target="_blank" rel="noreferrer noopener" aria-label="https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii#using-ldquo-natural-rdquo-routes (öffnet in neuem Tab)">https://spring.io/blog/2015/05/13/modularizing-the-client-angular-js-and-spring-security-part-vii#using-ldquo-natural-rdquo-routes</a></li>
</ul>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2019/02/angular-spring-boot/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>AngularJS Cheat Sheet</title>
		<link>https://sterl.org/2017/06/angularjs-cheat-sheet/</link>
					<comments>https://sterl.org/2017/06/angularjs-cheat-sheet/#comments</comments>
		
		<dc:creator><![CDATA[Paul Sterl]]></dc:creator>
		<pubDate>Fri, 23 Jun 2017 04:26:07 +0000</pubDate>
				<category><![CDATA[Angular]]></category>
		<category><![CDATA[Angular scope]]></category>
		<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[Component]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[State]]></category>
		<guid isPermaLink="false">http://sterl.org/?p=196</guid>

					<description><![CDATA[Create vs. Get AngularJS application The module dependency array tells AngularJS to create an app, otherwise to load it: Create myApp var app = angular.module('myApp', []); Get myApp var app = angular.module('myApp'); Binding @ Text binding, expressions are supported using {{ }} = Two-way binding &#38; Method binding &#60; One-way binding (usually for components) ?&#8230;]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">Create vs. Get AngularJS application </h3>



<p>The module dependency array tells AngularJS to create an app, otherwise to load it: </p>



<table class="wp-block-table"><tbody><tr><td>Create myApp</td><td><code>var app = angular.module('myApp', []);</code></td></tr><tr><td>Get myApp</td><td><code>var app = angular.module('myApp');</code></td></tr></tbody></table>



<h3 class="wp-block-heading"> Binding</h3>



<ul class="wp-block-list"><li> <code>@</code> Text binding, expressions are supported using <code>{{ }}</code></li><li><code>=</code> Two-way binding</li><li><code>&amp;</code> Method binding</li><li><code>&lt;</code> One-way binding (usually for <a rel="noreferrer noopener" href="https://docs.angularjs.org/guide/component" target="_blank">components</a>)</li><li><code>?</code> for an optional binding e.g. <code>@?</code> for an optional string binding </li></ul>



<h3 class="wp-block-heading">Service, Factory, Provider, Value &amp; Controller</h3>



<p><a rel="noreferrer noopener" href="https://docs.angularjs.org/guide/providers" target="_blank">AngularJS Doc</a></p>



<ul class="wp-block-list"><li>A <code>Service</code> is a singleton instance of a custom object. In can be used to share state or usually to wrap the remote REST API in a reuseable faction. It is injected using the name (<a rel="noreferrer noopener" href="http://cssdeck.com/labs/collab/qhvokdnt" target="_blank">review sample</a>).<br>Basically simple <em>AngularJs</em> beans we want to inject later. </li></ul>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/ecmascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">angular.module('myApp').service('myServiceName', ['depedency', function(depedency) {
    var privateState = {foo: 'bar'}; // this will be shared between any we inject this service
    this.publicApi = function(newConfig) {
        return privateState.foo; // shared singleton state
    };
}]);</pre></div>



<ul class="wp-block-list"><li>The <code>Factory</code> follows as the name already tells the factory pattern and so allows us to construct either a complex <code>value</code> we want to inject into our controllers or even already existing JS objects which require any dependencies upfront. Basically wrap beans which need a constructor injection (<a rel="noreferrer noopener" href="http://cssdeck.com/labs/collab/bpvsg28h" target="_blank">review sample</a>). </li></ul>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">// any bean
function myService($log) {
  this.log = $log;
}
myService.prototype.getState = function() {
  return this.state; // still shared if we like
}
//-- AngularJS starts here
// construct the bean and inject what is needed
angular.module('myApp', []).factory(
    'myServiceFactory', ['$log', function($log) {
  // here is the main difference to service,
  // manually call new
  return new myService($log);
}]);</pre></div>



<h4 class="wp-block-heading">Provider</h4>



<ul class="wp-block-list"><li>A <code>Provider</code> is the base for <code>factory</code> and <code>service</code> and has the biggest flexibility. Most important it can be injected into the config method and so configured before the first usage (<a rel="noreferrer noopener" href="http://cssdeck.com/labs/collab/bslsb0s2" target="_blank">review sample</a>).</li></ul>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">// my service / or just bean
function myService($log, initValue) {
  this.log = $log;
  this.state = {
    foo: initValue || 'Default state'
  };
  $log.info('Service Constructor called ...');
}
myService.prototype.getState = function() {
  this.log.info('getState called ...');
  return this.state;
}

// create angular myApp
var myApp = angular.module('myApp', []);
// register the provider providing our service
// function name is here only to how that this is the provider
myApp.provider('myService', function myServiceProvider() {
  // config area
  var providerState;
  this.config = function(newState) {
  	providerState = newState;
  };
  // constructor like in factory
  // again the name only indicates that here is where the factory function goes...
  this.$get = ['$log', function myServiceFactory($log) {
  	return new myService($log, providerState);
  }] 
});
// configure the provider / service
myApp.config(['myServiceProvider', function (myServiceProvider) {
	console.info('config:', myServiceProvider);
  myServiceProvider.config('configured state');
}]);
// just use it
myApp.component('c1', {
  controller: ['myService', function(myService) {
    this.state = myService.getState();
  }],
  template: 'C1: &lt;input ng-model=&quot;$ctrl.state.foo&quot;&gt;'
});
myApp.component('c2', {
  controller: ['myService', function(myService) {
    this.state = myService.getState();
  }],
  template: 'C2: &lt;input ng-model=&quot;$ctrl.state.foo&quot;&gt;'
});</pre></div>



<ul class="wp-block-list"><li>A <code>Value</code> is a simple object, int or string we want to make available for injection </li></ul>



<h2 class="wp-block-heading">HTML elements in AngularJS </h2>



<h3 class="wp-block-heading">Access HTML element Directive</h3>



<p> The easiest way is just to use the link method:  </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">angular.module('myApp).directive('myDirective', function () {
    return {
        restrict: 'A',
        replace : false,
        // scope, the element and the attributes
        link: function ($scope, element, attr) {
            // controller not needed if we have no public API
        }
    }
}</pre></div>



<h3 class="wp-block-heading">Access HTML element in Component </h3>



<p>In a component we can just inject the <code>$element</code>. </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">jsui.component('myComponent', {
        // first we can always inject the element of the component
        controller: ['$element', function ($element) {
            var subEl  = $element.find('.any-class'), // optional search by class
                rawDomEl = subEl[0]; // get the raw DOM element

            });
        }],
        templateUrl: 'app/myTemplate.html'
    });</pre></div>



<h3 class="wp-block-heading">Access raw HTML element </h3>



<p>As you can see in the last example we can access the raw DOM element using <code>[0]</code> on the wrapped element. </p>



<h2 class="wp-block-heading">Restrict in Angular <a rel="noreferrer noopener" href="https://docs.angularjs.org/guide/directive" target="_blank">Directive</a> </h2>



<p>The <code>restrict</code> option is typically set to: </p>



<ul class="wp-block-list"><li><code>'A'</code> &#8211; only matches attribute name</li><li><code>'E'</code> &#8211; only matches element name</li><li><code>'C'</code> &#8211; only matches class name</li><li><code>'M'</code> &#8211; only matches comment </li></ul>



<p> These restrictions can all be combined as needed: </p>



<ul class="wp-block-list"><li><code>'AEC'</code> &#8211; matches either attribute or element or class name </li></ul>



<h2 class="wp-block-heading">URL Routing to AngularJS components</h2>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">app.config(['$urlRouterProvider', '$stateProvider',
    function($urlRouterProvider, $stateProvider) {
            
        $urlRouterProvider.otherwise('/home');
            .state('home', {
                url: '/home',
                component: 'homeComponent'
            })
    })
    // this could be in an own file
    .component('homeComponent', {
        controller: function () {
            // this.title is available
            console.info(&quot;homeComponent loaded ...&quot;);
        },
        templateUrl: 'home/home.html'
    })
;</pre></div>



<h3 class="wp-block-heading">ocLazyLoad angular components during routing </h3>



<p>As the lifecycle of components is a bit different we have to eager load them using <a rel="noreferrer noopener" href="https://oclazyload.readme.io/" target="_blank">ocLazyLoad</a>: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">.state('home', {
    url: '/home',
    component: 'homeComponent',
    resolvePolicy: { deps: { when: &quot;EAGER&quot; } }, // LOAD EAGERLY
    resolve: {
        deps: ['$ocLazyLoad', function ($ocLazyLoad) {
          return $ocLazyLoad.load(
            { // best to store it static somewhere if needed more than once ...
              name: &quot;lazyHome&quot;,
              files: [&quot;home/homeComponent.js&quot;]
            }
          );
        }]
    }
});</pre></div>



<h3 class="wp-block-heading">Access URL parameters </h3>



<p>The easiest way to access the URL params is just to inject <code>$stateParams</code> into the component get read it. A bit cleaner is using the <code>resolve</code> of the <code>state</code> to inject the parameters into the component. As so we have to keep in mind that happens async, which means we have to implement the <code>$onInit</code> method to get hold of the injected values into our component. <a rel="noreferrer noopener" href="https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service" target="_blank">More to components.</a></p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">// given this state router we want to pass the vin to our component
.state('app.vehicle', {
    url: '/vehicle/:vin',
    component: 'vehicleComponent',
    // pass the vin from the URL to the component
    resolve: { 
        // could have the same name
        vehicleId: function($stateParams) { return $stateParams.vin; }
   }
})

// component using the VIN, here string binding
app.component('vehicleComponent', {
    bindings: {
        vehicleId: '@'
    },
    // we could access state passing here function($stateParams) 
    // and later with $stateParams.vin, which would couple URL id to components
    // and so we should better inject it ...
    controller: function () { 
        // async called INIT method vinComponent is set
        this.$onInit = function() {
            console.info(this.vehicleId);
        };
        // this is most likely not defined, as the resolve happens async
        console.info(this.vehicleId);
    },
    templateUrl: 'vehicle.html'
});</pre></div>



<h3 class="wp-block-heading">Dynamic ncyBreadcrumb label for AngularJS Components</h3>



<p>Accessing just the <code>$scope</code> doesn&#8217;t always work well during the reload of the page furthermore, it doesn&#8217;t work for components anyhow. The easiest way is just to inject the <code>$breadcrumb</code> service and be done with it: </p>



<div class="wp-block-codemirror-blocks-code-block code-block"><pre class="CodeMirror cm-s-material" data-setting="{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;javascript&quot;,&quot;mime&quot;:&quot;application/javascript&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;JavaScript&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;js&quot;}">// state definition
.state('app.customer', {
    url: '/customer/:customerId',
    component: 'customer',
    ncyBreadcrumb: {
        parent: 'app.customers',
        label: '{{ pageLabel || &quot;New Customer&quot; }}'
    }
});

// in the component just assign the label attribute in the ncyBreadcrumb
angular.module('myApp').component('customer', {
    bindings: {
        customerId: '@'
    },
    controller: ['$breadcrumb', function ($breadcrumb) {
        // set the page label
        $breadcrumb.$getLastViewScope().pageLabel = &quot;my page label&quot;;

    }],
    templateUrl: 'customer.html'
});</pre></div>
]]></content:encoded>
					
					<wfw:commentRss>https://sterl.org/2017/06/angularjs-cheat-sheet/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
	</channel>
</rss>
