<?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>Blog @ SIB Visions &#187; AngularJS</title>
	<atom:link href="http://blog.sibvisions.com/tag/angularjs/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.sibvisions.com</link>
	<description>Blog @ SIB Visions</description>
	<lastBuildDate>Mon, 13 Apr 2026 09:47:01 +0000</lastBuildDate>
		<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>AngularJS 4 with VisionX and JVx REST services</title>
		<link>https://blog.sibvisions.com/2017/10/23/angularjs-4-with-visionx-and-jvx-rest-services/</link>
		<comments>https://blog.sibvisions.com/2017/10/23/angularjs-4-with-visionx-and-jvx-rest-services/#comments</comments>
		<pubDate>Mon, 23 Oct 2017 21:58:43 +0000</pubDate>
		<dc:creator>rjahn</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[JVx]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">https://blog.sibvisions.com/?p=7337</guid>
		<description><![CDATA[Some time ago I wrote articles about my "web-technology" tests. The first article covered AngularJS with JVx in action. It was a simple list view for contacts, had an Edit form and was based on AngularJS 1.4. The second article was about Oracle JET with JVx. The result was another list view with contacts, without [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago I wrote articles about my "web-technology" tests. The first article covered <a href="https://blog.sibvisions.com/2015/06/15/angularjs-with-jvx-in-action/">AngularJS with JVx in action</a>. It was a simple list view for contacts, had an Edit form and was based on AngularJS 1.4. The second article was about <a href="https://blog.sibvisions.com/2016/02/29/using-oracle-jet-with-visionxjvx/">Oracle JET with JVx</a>. The result was another list view with contacts, without Edit form.</p>
<p>Both solutions were more or less a demonstration for the automatic REST interface of JVx but not a real technology PoC.</p>
<p>The second article about Oracle JET was written in Feb 2016 and the first, about AngularJS, was written in July 2015 - long time ago. Currently, Angular 4 is available and Angular 5 is coming. Big version jumps with big API changes and many new features.</p>
<p>Last week, I thought it might a good idea to start a new evaluation of AngularJS. One week later, I think different... but one step after another.</p>
<p>My plan was the creation of a very simple application with some enhanced features, like routing, CRUD, styling, custom components, REST with authentication, Deployment. This was the base idea because I read really cool marketing articles about Angular and thought it might be easy to create a simple application with expected features.</p>
<p><strong>So, what did I do to start?</strong></p>
<p>The <a href="https://angular.io/tutorial/">Angular tutorial</a> was great for a jump start. You'll build a smart heroes application with a small dashboard. Sure, it's not a real world application but has everything on board and hey, the Tutorial will show how to integrate REST services. I thought it might be an easy task and won't last more than 1 day!</p>
<p>The tutorial has 7 chapters and the last one integrates REST. The chapter 1 was easy, because it was the instruction <img src='https://blog.sibvisions.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  The second chapter contains the setup process which should be trivial, because I manually tried to create an AngularJS 4 application from scratch and it was super simple. But the setup for the tutorial wasn't easy because the creation of a new project from scratch contained too many files and the expected project layout (shown in the tutorial) was reduced to a bare minimum. It wasn't possible to delete all additional files because the project preview in the browser didn't work afterwards. So I decided to download the example archive.</p>
<p>This was the right decission because everything was pre-configured <img src='https://blog.sibvisions.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  First lesson learned: Project configuration is not easy and woha, many different config files.</p>
<p>It was super easy to follow the tutorial and chapters 3, 4 were relative short and fast to do. Starting with chapter 5, the whole thing was starting to get complex because Service integration, Routing and HTTP(REST) were complex things. The chapters 5, 6 and 7 are very long and boring because you have to do so many things (hey, it's a tutorial and it's good as it is!).<br />
No worries because I'm an "expert" and so I jumped to Chapter 6 and downloaded the finished example archive. The example was working without problems in my test environment <img src='https://blog.sibvisions.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  but it was without support for HTTP/REST calls because I thought it might be a good idea to integrate the features based on the tutorial on my own.</p>
<p>So the next step was the integration of my own REST service instead of the dummy service in the tutorial. But first... I needed a REST service.</p>
<p>The creation of a web service was super easy because of our <a href="https://visionx.sibvisions.com">Low Code Development Platform - VisionX</a>. It creates <a href="http://jvx.sibvisions.com/">JVx</a> based applications with all gimmicks. I did create a simple Heroes application with VisionX. The application has one screen:</p>
<div id="attachment_7339" class="wp-caption aligncenter" style="width: 310px"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/10/visionx_heroes_app.png" rel="lightbox[7337]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/10/visionx_heroes_app-300x228.png" alt="Heroes app created with VisionX" title="visionx_heroes_app" width="300" height="228" class="size-medium wp-image-7339" /></a><p class="wp-caption-text">Heroes app created with VisionX</p></div>
<p>The application was ready to use in 1 minute and had one database table:</p>
<div id="attachment_7341" class="wp-caption aligncenter" style="width: 310px"><a href="https://blog.sibvisions.com/wp-content/uploads/2017/10/visionx_heroes_dbmodel.png" rel="lightbox[7337]"><img src="https://blog.sibvisions.com/wp-content/uploads/2017/10/visionx_heroes_dbmodel-300x178.png" alt="Heroes table" title="visionx_heroes_dbmodel" width="300" height="178" class="size-medium wp-image-7341" /></a><p class="wp-caption-text">Heroes table</p></div>
<p>The heroes table contains the columns: ID and NAME. Thanks to JVx, the REST service was ready-to-use. The request: <em><strong>http://localhost/services/rest/Heroes/HeroesWorkScreen/data/heroes</strong></em></p>
<p>returned the JSON string with my test data:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="br0">&#91;</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;ID&quot;</span><span class="sy0">:</span> <span class="nu0">1</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;NAME&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Superman&quot;</span><br />
&nbsp; <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;ID&quot;</span><span class="sy0">:</span> <span class="nu0">4</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;NAME&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Rambo (John)&quot;</span><br />
&nbsp; <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;ID&quot;</span><span class="sy0">:</span> <span class="nu0">6</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;NAME&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Wolverine (X-Men)&quot;</span><br />
&nbsp; <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;ID&quot;</span><span class="sy0">:</span> <span class="nu0">2</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;NAME&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Batman&quot;</span><br />
&nbsp; <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;ID&quot;</span><span class="sy0">:</span> <span class="nu0">5</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;NAME&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Captain America&quot;</span><br />
&nbsp; <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="st0">&quot;ID&quot;</span><span class="sy0">:</span> <span class="nu0">3</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="st0">&quot;NAME&quot;</span><span class="sy0">:</span> <span class="st0">&quot;ANT MAN&quot;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#93;</span></div>
</div>
<p>So, my backend was ready.</p>
<p>The Next step was the integration into my Angular frontend. It was easy to find the right source file for the integration, because the hero-service was encapsulated. The first problem was that my REST service required authentication and the service implementation didn't use authentication. I had the same problem with missing authentication support in Angular 1.4 but found some useful things on stackoverflow. With Angular 4 everything has changed because you code Typescript and the API is different to 1.4, so my old solution didn't work. I tried to find something in the Internet but had a lot of problems because most help was for Angular 2. And I found so many github issues for http authentication and most issues had tons of comments... frustrating and not effective.</p>
<p>I tried to search in the official Angular documentation and found some hints about HttpClient in the <a href="https://angular.io/guide/http">online guide</a>. But I didn't know HttpClient because my example was created with HttpModule. Not helpful that the example from the tutorial is different to the official documentation.... or.... I didn't read the details.... or.... I'm a bad developer.... or (and this is a fact) my Javascript/Typescript know-how is not enough. But anyway, it was not a standard task to add authentication to my hero-service.</p>
<p>I'm not 100% sure how I solved the problem, but I guess I read the <a href="https://angular.io/api/http/RequestOptions">API doc about http</a> and an <a href="https://medium.com/google-developer-experts/angular-2-introduction-to-new-http-module-1278499db2a0">information about the new Angular2 HttpModule</a> (means that HttpModule is old and HttpClient is new?). I googled around for sime time and tried a lot of hints, but it was painful. So much documentation about such a simple problem and no concreate solution for the http authentication problem.</p>
<p>Here's my solution:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw2">export</span> <span class="kw2">class</span> HeroService <span class="br0">&#123;</span><br />
&nbsp; <br />
&nbsp; <span class="kw2">private</span> heroesUrl <span class="sy0">:</span> string<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span class="kw2">private</span> options <span class="sy0">:</span> RequestOptions<span class="sy0">;</span><br />
&nbsp; <span class="kw2">private</span> headers <span class="sy0">:</span> Headers<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; constructor<span class="br0">&#40;</span><span class="kw2">private</span> http<span class="sy0">:</span> Http<span class="br0">&#41;</span> <br />
&nbsp; <span class="br0">&#123;</span> <br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">headers</span> <span class="sy0">=</span> <span class="kw2">new</span> Headers<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">headers</span>.<span class="me1">append</span><span class="br0">&#40;</span><span class="st0">'Accept'</span><span class="sy0">,</span> <span class="st0">'application/json'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">headers</span>.<span class="me1">append</span><span class="br0">&#40;</span><span class="st0">'Content-Type'</span><span class="sy0">,</span> <span class="st0">'application/json'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">headers</span>.<span class="me1">append</span><span class="br0">&#40;</span><span class="st0">'Authorization'</span><span class="sy0">,</span> <span class="st0">'Basic '</span> <span class="sy0">+</span> btoa<span class="br0">&#40;</span><span class="st0">&quot;admin:admin&quot;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">options</span> <span class="sy0">=</span> <span class="kw2">new</span> RequestOptions<span class="br0">&#40;</span><span class="br0">&#123;</span> headers<span class="sy0">:</span> <span class="kw1">this</span>.<span class="me1">headers</span><span class="sy0">,</span> withCredentials<span class="sy0">:</span> <span class="kw2">true</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">heroesUrl</span> <span class="sy0">=</span> <span class="st0">'http://localhost/services/rest/Heroes/HeroesWorkScreen/data/heroes'</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span></p>
<p>&nbsp; getHeroes<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">:</span> Promise<span class="sy0">&lt;</span>Hero<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="sy0">&gt;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">return</span> <span class="kw1">this</span>.<span class="me1">http</span>.<span class="me1">get</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">heroesUrl</span><span class="sy0">,</span> <span class="kw1">this</span>.<span class="me1">options</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">toPromise</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="me1">then</span><span class="br0">&#40;</span>response <span class="sy0">=&gt;</span> response.<span class="me1">json</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">as</span> Hero<span class="br0">&#91;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .<span class="kw1">catch</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">handleError</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; <span class="br0">&#125;</span></p>
<p><span class="br0">&#125;</span></div>
</div>
<p>I know that username and admin are hard-coded but it's a simple test application without login. It's not really a problem to add a login form if needed and to replace the hard-coded values with variables.</p>
<p>After I solved the authentication problem, and everything was working in my test environment, I tried to continue with tutorial chapter 7 and tried to add new features like Adding new heroes, Deleting heroes. This was really straight forward and worked without problems, even with authentication.</p>
<p>Yuhu. After two days I had a working Angular 4 application which reads data from a REST service and offers CRUD. A simple routing was available and I had custom components, styling and was happy. I thought the next step should be a test deployment. Sounds easy and I thought it couldn't be a problem... but... deployment hell.</p>
<p><strong>Why is Angular deployment so complex?</strong></p>
<p>The documentation has a lot of information about <a href="https://angular.io/guide/deployment">deployment</a>. The simple deployment is really straight-forward because it's enough to copy/paste your development environment. But this is not recommended for production environments because of performance and many other things. So, i tried to deploy a production ready application and not my development environment... And the nightmare started.</p>
<p>I found a <a href="https://coursetro.com/posts/code/64/How-to-Deploy-an-Angular-App-(Angular-4)">super simple deployment guide for Angular 4</a>. First problem: didn't work for my example project because:</p>
<div class="codesnip-container" >Unable to find @angular/cli in devDependencies</p>
<p>Please take the following steps to avoid issues:<br />
"npm install --save-dev @angular/cli@latest"</p></div>
<p>After installing the missing module, the next problem:</p>
<div class="codesnip-container" >Cannot read property 'config' of null<br />
TypeError: Cannot read property 'config' of null</div>
<p>Also no problem because google found that my project needs an additional config file:</p>
<p><strong>.angular-cli.json</strong></p>
<p>I found this file in my demo Angular application, created from scratch. I tried to edit and adapt the file for my heroes application and the next problem came up:</p>
<div class="codesnip-container" >ENOENT: no such file or directory, stat '...\angular-tour-of-heroes\src\tsconfig.app.json'</div>
<p>No problem, same solution as before (copy/paste/change).</p>
<p>Hurray, the command:</p>
<div class="codesnip-container" >ng build -prod</div>
<p>was successful!</p>
<p>The dist folder contained my production ready application with 6 files! Great.</p>
<p>The deployment to my Tomcat application server was also super easy, because VisionX is able to create war files with a single mouse click. I changed the created war file and put the built Angular files in the root directory and deployed the war file.</p>
<p>No surprise, the application didn't work because some javascript files weren't found. The developer console of Chrome browser was a big help!</p>
<p><strong>So, what should I do?</strong></p>
<p>No... not Google. I read the development guide and found the solution in section <a href="https://angular.io/guide/deployment#load-npm-package-files-from-the-web-systemjs">Load npm package files from the web (SystemJS)</a>.</p>
<p>So, I changed my deployment and replaced <strong>node_modules</strong> in my <em>index.html</em> with <strong>https://unpkg.com/</strong>. This solved one problem but the developer console showed more 404 errors. I had to remove following:</p>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span>System.import('main.js').catch(function(err){ console.error(err); });<span class="sc2">&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span></div>
</div>
<p>and</p>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/link.html"><span class="kw2">link</span></a> <span class="kw3">rel</span><span class="sy0">=</span><span class="st0">&quot;stylesheet&quot;</span> <span class="kw3">href</span><span class="sy0">=</span><span class="st0">&quot;styles.css&quot;</span>&gt;</span></div>
</div>
<p>I also had to replace the <strong>node_modules</strong> path in systemjs.config.js with <strong>https://unpkg.com/</strong>. Oh, and the file was missing in dist folder. I decided to follow the deployment guide and created a file with the name <strong>systemjs.config.server.js</strong>. If you do this, the <strong>index.html</strong> needs a changed mapping.</p>
<p>I didn't replace the values by hand. Here's my ant build file:</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;"><span class="sc3"><span class="re1">&lt;project</span> <span class="re0">name</span>=<span class="st0">&quot;AngularJS&quot;</span> <span class="re0">default</span>=<span class="st0">&quot;start.complete&quot;</span><span class="re2">&gt;</span></span></p>
<p>&nbsp; <span class="sc-1">&lt;!--</span><br />
<span class="sc-1"> &nbsp;*****************************************************************</span><br />
<span class="sc-1"> &nbsp;* information</span><br />
<span class="sc-1"> &nbsp;*****************************************************************</span><br />
<span class="sc-1"> &nbsp;--&gt;</span></p>
<p>&nbsp; <span class="sc3"><span class="re1">&lt;description<span class="re2">&gt;</span></span></span>Angular JS deployment<span class="sc3"><span class="re1">&lt;/description<span class="re2">&gt;</span></span></span></p>
<p>&nbsp; <span class="sc-1">&lt;!--</span><br />
<span class="sc-1"> &nbsp;*****************************************************************</span><br />
<span class="sc-1"> &nbsp;* tasks</span><br />
<span class="sc-1"> &nbsp;*****************************************************************</span><br />
<span class="sc-1"> &nbsp;--&gt;</span></p>
<p>&nbsp; <span class="sc3"><span class="re1">&lt;target</span> <span class="re0">name</span>=<span class="st0">&quot;start.complete&quot;</span> <span class="re0">description</span>=<span class="st0">&quot;Prepares production files&quot;</span><span class="re2">&gt;</span></span></p>
<p>&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;property</span> <span class="re0">name</span>=<span class="st0">&quot;heroes&quot;</span> <span class="re0">location</span>=<span class="st0">&quot;D:/dev/other/angularjs/angular-tour-of-heroes&quot;</span> <span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;property</span> <span class="re0">name</span>=<span class="st0">&quot;dist&quot;</span> &nbsp; <span class="re0">location</span>=<span class="st0">&quot;${heroes}/dist&quot;</span> <span class="re2">/&gt;</span></span></p>
<p>&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replace</span> <span class="re0">file</span>=<span class="st0">&quot;${dist}/index.html&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacetoken<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[&lt;link rel=&quot;stylesheet&quot; href=&quot;styles.css&quot;&gt;]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacetoken<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacevalue<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacevalue<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/replace<span class="re2">&gt;</span></span></span></p>
<p>&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replace</span> <span class="re0">file</span>=<span class="st0">&quot;${dist}/index.html&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacetoken<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[&lt;script&gt;System.import('main.js').catch(function(err){ console.error(err); });&lt;/script&gt;]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacetoken<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacevalue<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacevalue<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/replace<span class="re2">&gt;</span></span></span></p>
<p>&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replace</span> <span class="re0">file</span>=<span class="st0">&quot;${dist}/index.html&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacetoken<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[node_modules/]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacetoken<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacevalue<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[https://unpkg.com/]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacevalue<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/replace<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replace</span> <span class="re0">file</span>=<span class="st0">&quot;${dist}/index.html&quot;</span> <span class="re0">encoding</span>=<span class="st0">&quot;UTF-8&quot;</span><span class="re2">&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacetoken<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[&lt;script src=&quot;systemjs.config.js&quot;&gt;&lt;/script&gt;]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacetoken<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;replacevalue<span class="re2">&gt;</span></span></span><span class="sc2">&lt;![CDATA[&lt;script src=&quot;systemjs.config.server.js&quot;&gt;&lt;/script&gt;]]&gt;</span><span class="sc3"><span class="re1">&lt;/replacevalue<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;/replace<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;copy</span> <span class="re0">file</span>=<span class="st0">&quot;${heroes}/src/systemjs.config.server.js&quot;</span> <span class="re0">tofile</span>=<span class="st0">&quot;${dist}/systemjs.config.server.js&quot;</span> <span class="re2">/&gt;</span></span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span class="sc3"><span class="re1">&lt;/target<span class="re2">&gt;</span></span></span></p>
<p><span class="sc3"><span class="re1">&lt;/project<span class="re2">&gt;</span></span></span></div>
</div>
<p>With above changes, it was possible to use my application with my tomcat application server. But I had two more problems!</p>
<p><strong>First</strong>, my REST service URL was wrong because it was set for my dev environment.<br />
<strong>Second</strong>, the browser reload of URLs didn't work because the application server returned 404 for e.g. <em>https://cloud.sibvisions.com/heroes/heroes/3</em></p>
<p>Two more problems, omg.</p>
<p>But clear, the REST service URL can't be the same in the prod environment. I saw that Angular comes with support for environments and thought this would solve my first problem.... No way!<br />
The problem was that the environment integration worked for build time, but not for development. It wasn't possible to import the environment constant in my Typescript files. It wasn't possible beause the file wasn't routed correctly and I didn't find a solution for this problem. The dev server returned 404 for the access to ../environments/environment.js. I tried to find a solution for more than one day, but gave up. I found out that the config files of an Angular application are evil. You have so many options and have absolutely no idea what's right. This is a common problem if you search the internet and it's a good idea to use a pre-created configuration. But the configuration of the heroes application was different to a newly created configuration. So I reverted all my environment changes and decided to follow the <a href="https://angular.io/guide/deployment#enable-production-mode">official documentation</a>. This  code is the clue:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw1">if</span> <span class="br0">&#40;</span><span class="sy0">!/</span>localhost<span class="sy0">/</span>.<span class="me1">test</span><span class="br0">&#40;</span>document.<span class="me1">location</span>.<span class="me1">host</span><span class="br0">&#41;</span><span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; enableProdMode<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>It doesn't read the value from the environment constant, as recommended <a href="http://tattoocoder.com/angular-cli-using-the-environment-option/">here</a>. Not sure if this was recommended in Angular 2 and not for Angular 4, but the support is still built-in. I found so many horrible solutions for the environment problem, but no simple and easy one.</p>
<p>I solved the problem with my heroes-service and static properties. Yep, static field properties. It's that easy!</p>
<p>Here's a snippet from my service:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw2">export</span> <span class="kw2">class</span> HeroService <span class="br0">&#123;</span><br />
&nbsp; <br />
&nbsp; <span class="kw2">private</span> static heroesUrl <span class="sy0">:</span> string<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; <span class="kw2">public</span> static initMode<span class="br0">&#40;</span>prodMode<span class="sy0">:</span> boolean<span class="br0">&#41;</span><span class="sy0">:</span> <span class="kw1">void</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>prodMode<span class="br0">&#41;</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; enableProdMode<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; HeroService.<span class="me1">heroesUrl</span> <span class="sy0">=</span> <span class="st0">'https://cloud.sibvisions.com/heroes/services/rest/Heroes/HeroesWorkScreen/data/heroes'</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="kw1">else</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; HeroService.<span class="me1">heroesUrl</span> <span class="sy0">=</span> <span class="st0">'http://localhost/services/rest/Heroes/HeroesWorkScreen/data/heroes'</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#125;</span><br />
...</div>
</div>
<p>I used the recommended environment detection in my main.ts:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;">HeroService.<span class="me1">initMode</span><span class="br0">&#40;</span><span class="sy0">!/</span>localhost<span class="sy0">/</span>.<span class="me1">test</span><span class="br0">&#40;</span>document.<span class="me1">location</span>.<span class="me1">host</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<p>This solved my environment problem completely. I'm not sure what's the best solution and I would recommend the built-in environment solution, but there should be a working tutorial or example for development and deployment.</p>
<p>Second lesson learned: Deployment is not easy with Angular if you want to make it right. The documentation is not clear and it's complex!!!</p>
<p>Back to my second problem: browser reload!<br />
This is documented <a href="https://angular.io/guide/deployment#routed-apps-must-fallback-to-indexhtml">here</a>. Clear, isn't it?</p>
<p>So, no solution for my Apache Tomcat installation. Rewrite rules are supported but why so tricky? I won't configure routing in my application and in the application server. This should simply work.<br />
I tried to find a simple solution and created a simple Filter, because too much configuration was not what I want!</p>
<p>My filter:</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">public</span> <span class="kw4">void</span> doFilter<span class="br0">&#40;</span>ServletRequest pRequest, ServletResponse pResponse, FilterChain pChain<span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">IOException</span>, ServletException<br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw3">String</span> sURI <span class="sy0">=</span> <span class="br0">&#40;</span><span class="br0">&#40;</span>HttpServletRequest<span class="br0">&#41;</span>pRequest<span class="br0">&#41;</span>.<span class="me1">getRequestURI</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>StringUtil.<span class="me1">isEmpty</span><span class="br0">&#40;</span>FileUtil.<span class="me1">getExtension</span><span class="br0">&#40;</span>sURI<span class="br0">&#41;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; RequestDispatcher reqdis <span class="sy0">=</span> pRequest.<span class="me1">getRequestDispatcher</span><span class="br0">&#40;</span>sIndex<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; reqdis.<span class="me1">forward</span><span class="br0">&#40;</span>pRequest, pResponse<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; pChain.<span class="me1">doFilter</span><span class="br0">&#40;</span>pRequest, pResponse<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span></div>
</div>
<p>Configration (web.xml):</p>
<div class="codesnip-container" >
<div class="xml codesnip" style="font-family:monospace;"><span class="sc3"><span class="re1">&lt;filter<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;filter-name<span class="re2">&gt;</span></span></span>IndexHtmlFilter<span class="sc3"><span class="re1">&lt;/filter-name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;filter-class<span class="re2">&gt;</span></span></span>demo.angular.IndexHtmlFilter<span class="sc3"><span class="re1">&lt;/filter-class<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;init-param<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;param-name<span class="re2">&gt;</span></span></span>index<span class="sc3"><span class="re1">&lt;/param-name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp; <span class="sc3"><span class="re1">&lt;param-value<span class="re2">&gt;</span></span></span>/app/index.html<span class="sc3"><span class="re1">&lt;/param-value<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;/init-param<span class="re2">&gt;</span></span></span><br />
&nbsp;<span class="sc3"><span class="re1">&lt;/filter<span class="re2">&gt;</span></span></span><br />
&nbsp;<br />
&nbsp;<span class="sc3"><span class="re1">&lt;filter-mapping<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;filter-name<span class="re2">&gt;</span></span></span>IndexHtmlFilter<span class="sc3"><span class="re1">&lt;/filter-name<span class="re2">&gt;</span></span></span><br />
&nbsp; &nbsp;<span class="sc3"><span class="re1">&lt;url-pattern<span class="re2">&gt;</span></span></span>/app/*<span class="sc3"><span class="re1">&lt;/url-pattern<span class="re2">&gt;</span></span></span><br />
&nbsp;<span class="sc3"><span class="re1">&lt;/filter-mapping<span class="re2">&gt;</span></span></span></div>
</div>
<p>Not my best code, but works.... if you put the application in a seperate folder... e.g. The REST servic call:</p>
<p>//souldn't route to index.html<br />
<em>https://cloud.sibvisions.com/heroes/services/rest/Heroes/HeroesWorkScreen/data/heroes </em></p>
<p>//should route to index.html<br />
<em>https://cloud.sibvisions.com/heroes/heroes/2</em></p>
<p>So it was easier to move the application into a sub directory: /app<br />
<em>https://cloud.sibvisions.com/heroes/<strong>app/</strong>heroes/2</em></p>
<p>and everything starting with /app/* will be routed to /app/index.html if necessary.</p>
<p>This configuration and the filter solved my second problem and hurray, my application was working without any problems!</p>
<p>Oh, in order to serve my application from the /app directory, I had to set the base href in index.html:</p>
<div class="codesnip-container" >ng build -prod --base-href /heroes/app/</div>
<p>Here's the application: <a href="https://cloud.sibvisions.com/heroes/app/">https://cloud.sibvisions.com/heroes/app/</a><br />
(Please don't delete my default heroes because there's no "restore defaults" implemented)</p>
<p><strong>What's next?</strong></p>
<p>I wasn't happy with default features of tutorial app because I missed an export feature. So I decided to add a Report which contains all my heroes. The REST service was ready in one minute because VisionX has Reporting support. But how to download/save the report?</p>
<p>I had no example and google returned too many answers for Angular 2 and one for <a href="https://shekhargulati.com/2017/07/16/implementing-file-save-functionality-with-angular-4/">Angular 4</a>. I followed the instructions and had many problems because the saveAs method wasn't found... So I had the next big problem!</p>
<p>Every new feature was a big problem for me <img src='https://blog.sibvisions.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This feature was horrible because I had absolutely no plan about angular modules. I found several save-file modules and tried to install one by one. No module was working as documented. Not sure if the problem was because of my configuration or because of Angular 4. Finally I found <a href="https://stackoverflow.com/questions/40240796/angular-2-best-approach-to-use-filesaver-js">one solution</a> but I had to change my system.config.js manually and add:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="st0">'file-saver'</span><span class="sy0">:</span> <span class="st0">'npm:file-saver'</span></div>
</div>
<p>to the system loader and</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="st0">'file-saver'</span><span class="sy0">:</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; format<span class="sy0">:</span> <span class="st0">'global'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; main<span class="sy0">:</span> <span class="st0">'FileSaver.js'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; defaultExtension<span class="sy0">:</span> <span class="st0">'js'</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span></div>
</div>
<p>to the packages.</p>
<p>I don't know why the default module installation didn't work but it did not! </p>
<p>After everything worked in my dev environment, I tried the same application in my prod environment and... error.<br />
The FileSaver.js was not found???</p>
<p>Absolutely unclear, but I solved the problem dirty (or not) in my index.html. Simply added </p>
<div class="codesnip-container" >
<div class="html4strict codesnip" style="font-family:monospace;"><span class="sc2">&lt;<a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a> <span class="kw3">src</span><span class="sy0">=</span><span class="st0">&quot;node_modules/file-saver/FileSaver.min.js&quot;</span>&gt;&lt;<span class="sy0">/</span><a href="http://december.com/html/4/element/script.html"><span class="kw2">script</span></a>&gt;</span></div>
</div>
<p>and it was find in dev and prod environment.</p>
<p>... I thought.</p>
<p>One more problem: Download worked but the content was damaged!</p>
<p>The problem was related to the content-type or maybe the encoding?</p>
<p>Recommended (<a href="https://shekhargulati.com/2017/07/16/implementing-file-save-functionality-with-angular-4/">Solution 1</a>, <a href="https://www.npmjs.com/package/file-saver">Solution 2</a>) solution:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw1">this</span>.<span class="me1">http</span>.<span class="me1">post</span><span class="br0">&#40;</span>HeroService.<span class="me1">heroesUrlAction</span> <span class="sy0">+</span> <span class="st0">'createListReportHeroes'</span><span class="sy0">,</span> JSON.<span class="me1">stringify</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span class="kw2">null</span><span class="sy0">,</span> <span class="kw2">null</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.<span class="me1">toPromise</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.<span class="me1">then</span><span class="br0">&#40;</span>response <span class="sy0">=&gt;</span> <span class="br0">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw2">var</span> blob <span class="sy0">=</span> <span class="kw2">new</span> Blob<span class="br0">&#40;</span><span class="br0">&#91;</span>response._body<span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#123;</span>type<span class="sy0">:</span> <span class="st0">'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;saveAs<span class="br0">&#40;</span>blob<span class="sy0">,</span> <span class="st0">'report.xlsx'</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.<span class="kw1">catch</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">handleError</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<p>This wasn't working because something was missing:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="kw2">var</span> optCopy <span class="sy0">=</span> <span class="kw2">new</span> RequestOptions<span class="br0">&#40;</span><span class="br0">&#123;</span> headers<span class="sy0">:</span> <span class="kw1">this</span>.<span class="me1">headers</span><span class="sy0">,</span> withCredentials<span class="sy0">:</span> <span class="kw2">true</span><span class="sy0">,</span> responseType<span class="sy0">:</span> ResponseContentType.<span class="me1">Blob</span> <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;+</span></p>
<p>&nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">http</span>.<span class="me1">post</span><span class="br0">&#40;</span>HeroService.<span class="me1">heroesUrlAction</span> <span class="sy0">+</span> <span class="st0">'createListReportHeroes'</span><span class="sy0">,</span> JSON.<span class="me1">stringify</span><span class="br0">&#40;</span><span class="br0">&#91;</span><span class="kw2">null</span><span class="sy0">,</span> <span class="kw2">null</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">,</span> optCopy<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.<span class="me1">toPromise</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.<span class="me1">then</span><span class="br0">&#40;</span>response <span class="sy0">=&gt;</span> <span class="br0">&#123;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw2">var</span> blob <span class="sy0">=</span> <span class="kw2">new</span> Blob<span class="br0">&#40;</span><span class="br0">&#91;</span>response.<span class="me1">blob</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#93;</span><span class="sy0">,</span> <span class="br0">&#123;</span>type<span class="sy0">:</span> <span class="st0">'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;saveAs<span class="br0">&#40;</span>blob<span class="sy0">,</span> <span class="st0">'report.xlsx'</span><span class="br0">&#41;</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;.<span class="kw1">catch</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">handleError</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<p>Clear, the ResponseContentType.Blob has to be set!!!<br />
And if you set this type, the response._body throws a warning? Use response.blob() instead!</p>
<p>It took me one hour to remove this warning!</p>
<p><strong>Next?</strong></p>
<p>I'm done!</p>
<p>The whole application development made me 1 year older because of frustration. I know that I'm not an Angular expert and I didn't read everything in the official documentation or guide/tutorial, but the whole development was a torture - sure, the result is great!</p>
<p>Too many different solutions for simple problems: deployment, downloading a file, configuration.</p>
<p>The documentation is awesome but too complex and contains no simple use cases. A simple deployment would be awesome and the problem with environments was horrible. Angular is powerful, no doubt! The configuration and deployment aren't straight forward. Also the mechanism behind the module system was not always working, at least not for me.</p>
<p>I love using custom components and the styling integration is great. The routing configuration is error-prone without an IDE or specific tools. My application didn't use all available features like testing, linting, ...</p>
<p><strong>Finally</strong></p>
<p>The application is available as JVx application with Vaadin UI <a href="https://cloud.sibvisions.com/heroes/web/ui/">here</a>.<br />
Login with admin as username and password.</p>
<p>The <a href="https://cloud.sibvisions.com/heroes/app/">Angular 4 application</a>.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2017/10/23/angularjs-4-with-visionx-and-jvx-rest-services/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>AngularJS with JVx in action</title>
		<link>https://blog.sibvisions.com/2015/06/15/angularjs-with-jvx-in-action/</link>
		<comments>https://blog.sibvisions.com/2015/06/15/angularjs-with-jvx-in-action/#comments</comments>
		<pubDate>Mon, 15 Jun 2015 11:34:40 +0000</pubDate>
		<dc:creator>rjahn</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[AngularJS]]></category>
		<category><![CDATA[JVx]]></category>

		<guid isPermaLink="false">http://blog.sibvisions.com/?p=4532</guid>
		<description><![CDATA[Our JVx library has REST support since 2011. It's not only support for using REST libraries, it's a generic solution for action calls and storage access (e.g. database records). This means that your whole business logic is usable via REST with same security restrictions as usual.
In 2011, REST wasn't as popular as today and not [...]]]></description>
			<content:encoded><![CDATA[<p>Our JVx library has REST support since 2011. It's not only support for using REST libraries, it's a generic solution for action calls and storage access (e.g. database records). This means that your whole business logic is usable via REST with same security restrictions as usual.</p>
<p>In 2011, REST wasn't as popular as today and not supported from soo many different frameworks than today. But now, in 2015, SOAP is legacy and REST is the thing to use. I'm sure you have heard about this modern JavaScript frameworks like <a href="https://angularjs.org/">AngularJS</a>.</p>
<p>Not sure if it's so successful because it's from Google, but it's often used and developers love working with AngularJS. So we started a simple research project to connect an AngularJS app to our JVx backend application.</p>
<p>AngularJS and <a href="http://sourceforge.net/projects/jvx/">JVx</a> is a perfect match because Angular was designed for JS frontends and JVx provides your business logic. Sure, JVx is a full-stack framework and you could create the whole web application, based on vaadinUI, but it's also open for all other UIs.</p>
<p>The most important thing is that everything works out-of-the-box. No additional coding for REST services or authentication, no special knowledge needed. Here's an example service for accessing a customer table (full CRUD support):</p>
<div class="codesnip-container" >
<div class="java codesnip" style="font-family:monospace;"><span class="kw1">public</span> <span class="kw1">class</span> Customers <span class="kw1">extends</span> Session<br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">public</span> DBStorage getCustomer<span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="kw1">throws</span> <span class="kw3">Exception</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DBStorage dbsCustomer <span class="sy0">=</span> <span class="br0">&#40;</span>DBStorage<span class="br0">&#41;</span>get<span class="br0">&#40;</span><span class="st0">&quot;customer&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span>dbsCustomer <span class="sy0">==</span> <span class="kw2">null</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsCustomer <span class="sy0">=</span> <span class="kw1">new</span> DBStorage<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsCustomer.<span class="me1">setWritebackTable</span><span class="br0">&#40;</span><span class="st0">&quot;customer&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsCustomer.<span class="me1">setDBAccess</span><span class="br0">&#40;</span>getDBAccess<span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dbsCustomer.<span class="me1">open</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; put<span class="br0">&#40;</span><span class="st0">&quot;customer&quot;</span>, dbsCustomer<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> dbsCustomer<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>The class was copied from our <a href="https://cloud.sibvisions.com/demoerp/web/ui?Application.Login.username=manager&#038;Application.Login.password=manager&#038;Application.WelcomeScreen=com.sibvisions.apps.demoerp.screens.CustomersWorkScreen" target="_blank">DemoERP</a> application (Login as: <em>manager</em> with password: <em>manager</em>). The source code of the whole application is available <a href="http://sourceforge.net/projects/erpdemoapplication/">here</a>.</p>
<p>Yes, there are no more methods like save, update, delete, query, ... The DBStorage encapsulates all calls for you and our <a href="http://sourceforge.net/p/jvx/code/HEAD/tree/trunk/java/library/src/com/sibvisions/rad/server/http/rest/RESTAdapter.java">generic REST service</a> handles the communication with your business logic.</p>
<p>We have a simple Angular app for you (<em>click on the pencil to edit the record</em>):</p>
<p><iframe src="https://cloud.sibvisions.com/angularjs/" style="width: 100%; height: 400px; border:0"></iframe></p>
<p>This solution is based on <a href="https://angularjs.org/">AngularJS 1.4.0</a>, <a href="http://getbootstrap.com/">Bootstrap 3.3.4</a> on client-side and JVx with RESTlet on server-side. Here's the JS file:</p>
<div class="codesnip-container" >
<div class="javascript codesnip" style="font-family:monospace;"><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw2">var</span> app <span class="sy0">=</span> angular.<span class="me1">module</span><span class="br0">&#40;</span><span class="st0">'contactApp'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st0">'ngResource'</span><span class="sy0">,</span> <span class="st0">'ngRoute'</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; app.<span class="me1">config</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>$routeProvider<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; $routeProvider.<span class="me1">when</span><span class="br0">&#40;</span><span class="st0">'/'</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; controller<span class="sy0">:</span><span class="st0">'ListContactsController as contactList'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; templateUrl<span class="sy0">:</span><span class="st0">'list.html'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; resolve<span class="sy0">:</span> <span class="br0">&#123;</span>contacts<span class="sy0">:</span> <span class="kw2">function</span> <span class="br0">&#40;</span>Contacts<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> Contacts.<span class="me1">fetch</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; .<span class="me1">when</span><span class="br0">&#40;</span><span class="st0">'/edit/:contactId'</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; controller<span class="sy0">:</span><span class="st0">'EditContactController as editContact'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; templateUrl<span class="sy0">:</span><span class="st0">'edit.html'</span> &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; .<span class="me1">otherwise</span><span class="br0">&#40;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; redirectTo<span class="sy0">:</span><span class="st0">'/'</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; app.<span class="me1">factory</span><span class="br0">&#40;</span><span class="st0">'ContactsFactory'</span><span class="sy0">,</span> <span class="br0">&#91;</span><span class="st0">'$resource'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>$resource<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw2">var</span> auth <span class="sy0">=</span> <span class="st0">'Basic '</span> <span class="sy0">+</span> btoa<span class="br0">&#40;</span><span class="st0">&quot;manager:manager&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> $resource<span class="br0">&#40;</span><span class="st0">'/demoerp/services/rest/DemoERP/Customers/data/customer/:contactId'</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">null</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><span class="st0">'get'</span><span class="sy0">:</span> &nbsp; &nbsp;<span class="br0">&#123;</span>method<span class="sy0">:</span><span class="st0">'GET'</span><span class="sy0">,</span> headers<span class="sy0">:</span> <span class="br0">&#123;</span><span class="st0">'Authorization'</span><span class="sy0">:</span>auth<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">'save'</span><span class="sy0">:</span> &nbsp; <span class="br0">&#123;</span>method<span class="sy0">:</span><span class="st0">'POST'</span><span class="sy0">,</span> headers<span class="sy0">:</span> <span class="br0">&#123;</span><span class="st0">'Authorization'</span><span class="sy0">:</span>auth<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">'update'</span><span class="sy0">:</span> <span class="br0">&#123;</span>method<span class="sy0">:</span><span class="st0">'PUT'</span><span class="sy0">,</span> headers<span class="sy0">:</span> <span class="br0">&#123;</span><span class="st0">'Authorization'</span><span class="sy0">:</span>auth<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">'query'</span><span class="sy0">:</span> &nbsp;<span class="br0">&#123;</span>method<span class="sy0">:</span><span class="st0">'GET'</span><span class="sy0">,</span> isArray<span class="sy0">:</span><span class="kw2">true</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; headers<span class="sy0">:</span> <span class="br0">&#123;</span><span class="st0">'Authorization'</span><span class="sy0">:</span>auth<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="st0">'delete'</span><span class="sy0">:</span> <span class="br0">&#123;</span>method<span class="sy0">:</span><span class="st0">'DELETE'</span><span class="sy0">,</span> headers<span class="sy0">:</span> <span class="br0">&#123;</span><span class="st0">'Authorization'</span><span class="sy0">:</span>auth<span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#93;</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp;</p>
<p>&nbsp; &nbsp; app.<span class="me1">service</span><span class="br0">&#40;</span><span class="st0">'Contacts'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>$q<span class="sy0">,</span> $http<span class="sy0">,</span> ContactsFactory<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw2">var</span> self <span class="sy0">=</span> <span class="kw1">this</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">fetch</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> deferred <span class="sy0">=</span> $q.<span class="me1">defer</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> ContactsFactory.<span class="me1">query</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>data<span class="sy0">,</span> <span class="kw3">status</span><span class="sy0">,</span> headers<span class="sy0">,</span> config<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self.<span class="me1">contacts</span> <span class="sy0">=</span> data<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deferred.<span class="me1">resolve</span><span class="br0">&#40;</span>data<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">function</span><span class="br0">&#40;</span>data<span class="sy0">,</span> <span class="kw3">status</span><span class="sy0">,</span> headers<span class="sy0">,</span> config<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; console.<span class="me1">log</span><span class="br0">&#40;</span><span class="st0">&quot;Error while received data.&quot;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; deferred.<span class="me1">reject</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> deferred.<span class="me1">promise</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; app.<span class="me1">controller</span><span class="br0">&#40;</span><span class="st0">'ListContactsController'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>contacts<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> contactList <span class="sy0">=</span> <span class="kw1">this</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; contactList.<span class="me1">contacts</span> <span class="sy0">=</span> contacts<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <br />
&nbsp; &nbsp; app.<span class="me1">controller</span><span class="br0">&#40;</span><span class="st0">'EditContactController'</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span>$location<span class="sy0">,</span> $routeParams<span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Contacts<span class="sy0">,</span> ContactsFactory<span class="br0">&#41;</span> <br />
&nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> editContact <span class="sy0">=</span> <span class="kw1">this</span><span class="sy0">;</span></p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">fillData</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw2">var</span> idx <span class="sy0">=</span> Contacts.<span class="me1">contacts</span>.<span class="me1">reduce</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span>cur<span class="sy0">,</span> val<span class="sy0">,</span> index<span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">if</span> <span class="br0">&#40;</span>val.<span class="me1">ID</span> <span class="sy0">==</span> $routeParams.<span class="me1">contactId</span> <span class="sy0">&amp;&amp;</span> cur <span class="sy0">==</span> <span class="sy0">-</span>1 <span class="br0">&#41;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">return</span> index<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="kw1">return</span> cur<span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">,</span> <span class="sy0">-</span>1<span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editContact.<span class="me1">contact</span> <span class="sy0">=</span> Contacts.<span class="me1">contacts</span><span class="br0">&#91;</span>idx<span class="br0">&#93;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; editContact.<span class="me1">save</span> <span class="sy0">=</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ContactsFactory.<span class="me1">update</span><span class="br0">&#40;</span><span class="br0">&#123;</span>contactId <span class="sy0">:</span> $routeParams.<span class="me1">contactId</span><span class="br0">&#125;</span><span class="sy0">,</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;editContact.<span class="me1">contact</span><span class="sy0">,</span> <span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $location.<span class="me1">path</span><span class="br0">&#40;</span><span class="st0">'/'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">if</span> <span class="br0">&#40;</span><span class="kw1">typeof</span> Contacts.<span class="me1">contacts</span> <span class="sy0">==</span> <span class="st0">'undefined'</span><span class="br0">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Contacts.<span class="me1">fetch</span><span class="br0">&#40;</span><span class="br0">&#41;</span>.$promise.<span class="me1">then</span><span class="br0">&#40;</span><span class="kw1">this</span>.<span class="me1">fillData</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">else</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">this</span>.<span class="me1">fillData</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><br />
&nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span><span class="sy0">;</span> &nbsp; &nbsp;<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span></div>
</div>
<p>It's a useful script because it combines REST with Basic authentication for querying and updating remote database records. Sure, it's not a fat application but this wasn't our intention <img src='https://blog.sibvisions.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>We have a <a href="http://blog.sibvisions.com/wp-content/uploads/2015/06/angularjs.war">web application archive</a> for you, if you're interested. Simply use this war together with our <a href="http://sourceforge.net/projects/erpdemoapplication/">DemoERP</a> application and install both applications on e.g. Tomcat application server.</p>
]]></content:encoded>
			<wfw:commentRss>https://blog.sibvisions.com/2015/06/15/angularjs-with-jvx-in-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
