import { BrowserModule } from '@angular/platform-browser'; import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from '@angular/core'; import { LazyElementsModule } from '@angular-extensions/elements'; import { AppComponent } from './app.component'; import { CoverComponent } from './cover/cover.component'; @NgModule({ declarations: [ AppComponent, CoverComponent ], imports: [ BrowserModule, LazyElementsModule, ], providers: [], bootstrap: [AppComponent], schemas: [CUSTOM_ELEMENTS_SCHEMA], }) export class AppModule { }
@Component({ selector: 'app-cover', template: `Shows the webcomponent below
` }) export class CoverComponent { handleEvent(event: any): void { console.log(`His name is ${event.detail.name}`); } }
import { BrowserModule } from '@angular/platform-browser'; import { NgModule, Injector } from '@angular/core'; import { createCustomElement } from '@angular/elements'; import { AppComponent } from './app.component'; import { WidgetComponent} from './widget-component/widget-component.component'; @NgModule({ declarations: [ AppComponent, WidgetComponent ], imports: [ BrowserModule ], providers: [], entryComponents: [ AppComponent, WidgetComponent ] }) export class AppModule { constructor(private injector: Injector) { } ngDoBootstrap(): void { const ngCustomElement = createCustomElement(WidgetComponent, { injector: this.injector }); customElements.define('widget-component', ngCustomElement); } }
import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ // tslint:disable-next-line:component-selector selector: 'widget-component', template: `Hello {{ name }}
`, styleUrls: ['./widget.component.css'] }) export class WidgetComponent { @Input() name: string; @Output() hello = new EventEmitter(); }
{ ... "architect": { ... "build": { "builder": "ngx-build-plus:build", ... }, ... "serve": { "builder": "ngx-build-plus:dev-server", ... }, "test": { "builder": "ngx-build-plus:karma", ... }, ... }, ... }
{ "start": "npm run build && serve -l 5001 dist/widget-app", "build": "ng build --prod --output-hashing none --single-bundle true", }
$ node -v
$ npm -v
If you have it installed, the terminal should return a version of tools.
$ npm install -g @angular/cli
The -g flag ensures that the package is installed globally,
as opposed to installing a package for a given directory. Our next step will be creating an angular project. To make it happen, go to your chosen directory and type
$ ng new first-angular-electron-app
The command might take a while, as it is creating a new workspace and an initial Angular application. Go grab yourself a cup of coffee!
After a while, there will be a new first-angular-electron-app created inside your base directory. In the following steps, we will go to the directory created by Angular CLI command, install the required packages specified in
package.json file created by ng new and run the app.
Type in the following:
$ cd first-angular-electron-app
$ npm install
$ npm link #make sure packages are linked
$ ng serve
Running ng serve builds and serves the app, also coming with the feature of rebuilding app on any file changes. By default, Angular starts on port 4200. Go to your favourite browser and paste
localhost:4200 to see the results.
$ npm install --save-dev electron
The --save-dev is a flag, which is used to save the given package for development purposes.
$ touch main.js
Then, open the content of the main.js file and paste the following code
snippet:
const {app, BrowserWindow} = require('electron');
const url = require('url');
const path = require('path');
function onReady () {
win = new BrowserWindow({width: 900, height: 6700})
win.loadURL(url.format({
pathname: path.join(
__dirname,
'dist/first-angular-electron-app/index.html'),
protocol: 'file:',
slashes: true
}))
}
app.on('ready', onReady);
Remember, you have to specify the correct path to the
index.html file, that can be found in dist folder (created by build command in the following step). In case you named your app different to first-angular-electron-app make sure to update pathname in
main.js file.
<base href="/">
to
<base href="./">
to make sure that
JS files will be visible for Electron. The last step will be configuring
the package.json to build the Angular App and correctly run the Electron.
...,
"main" : "main.js",
...,
"scripts": {
...,
“electron”: “ng build && electron .”
}
The modifications are specifying the main file for Electron. The
electron command in scripts object is our bootstrap command
for building the Angular App (the artficats will be pushed into dist folder)
and running the electron process. To run our Angular Desktop App
type in your root directory:
$ npm run electron
Take another sip of your drink and after a while... boom!
As a company that has a specializes in migrations, we understand the frustrations when it comes to the migration from AngularJS to Angular, especially when issues arise due to differences between Promises in AngularS and Observables in Angular2+.
In this article, we would like to highlight the key differences between Promises and Observables and clear confusions that you may have.
Promises are commonly used in AngularJS to handle HTTP requests. After making a request, a single response is expected with which the promise is resolved as in the example below:
However, resolving a Promise again with a different value will not work. It is always resolved with the initial value passed to the resolve function and disregards next calls to it:
In contrast to Promises, Observables emit a stream of one or multiple values that are all passed to their subscribers as illustrated in the example below. Typically, the Angular HTTP service provides an Observable stream with one response value, making its behaviour alike to a Promise.
In basic migration scenarios, the AngularJS $http service can be replaced by the Angular httpService. However, if you are dealing with more complex applications there a many key differences to pay attention to. Hereafter, we will discuss the most common differences:
In the example above, when you call the saveChanges method, the initial Promise-wrapped request will function. While Promises are eager-evaluated, Observable-wrapped requests will not do anything as Observables are lazy-evaluated.
Observables will be called only if you subscribe to them. In the previous case, the post Observable needs to be subscribed as follows for the http called to be executed:
Let us have an example where on input text change from the user a search is requested on the backend. One major disadvantage is that you cannot reject the results of the initial request if you keep typing. Although you can ease this problem with a debounce, it does not entirely resolve the problem. Further on, there is a possibility of race conditions, which means that an incorrect response will be displayed due to the later request result coming back before earlier requests.
An Observable eliminates this issue elegantly with the use of the switchMap operator:
In this example, the input text typing is converted to an observable value stream. Each time a new text value is being emitted, the switchMap operator will cancel the last network requests and send a new one, if the last one is not finished.
Implementing a retry logic with Promises is a complex exercise that typically ends in a variation of the following code:
However, with Observables the same retry logic is implemented with the following one-liner!
Promises only have two combination tools:
In contrast, Observables have a variety of combinations:
And so much more: window, switchMap, partition, groupBy, mergeMap, iif, etc.
To conclude, when you migrate from AngularJS that uses Promises for HTTP calls to Angular2+ that uses Observables, you need to be careful about the differences between the two frameworks. In particular, Observables offer powerful combination tools that should be leveraged to simplify the codebase.
We hope that this article was helpful to you and clarified differences that will ease your future developments or migration!
Hope you enjoyed today's #MondayBlog about Observable best practices. For more content, follow us on LinkedIn and subscribe to the newsletter on our website, and we will make sure that you’ll not miss out on anything! Have a great and productive week and see you at the next #MondayBlog by LogicFlow!
![]() |
FOLLOW
FOLLOW CONTACT US |
Zurich, January 8th, 2021 – LogicFlow AG, a start-up founded in 2020 announced today the closing of its CHF 0.5 million pre-seed round from Swiss Angel investors and Venture Kick for its one-of-a-kind code migration technology. LogicFlow is a Zurich-based startup driving automation in the software development industry. With the funding, LogicFlow will further develop and scale its leading software code translation and generation technology.
LogicFlow developed a first of its kind automation system for software migration,
enabling corporations to modernize faster and at a significantly lower cost.
Modernization is a major challenge for IT departments, as organizations evolve,
they suffer from decreasing productivity due to the technical debt in their
legacy systems. With the LogicFlow technology, repetitive code migration tasks
are automated, helping companies to migrate, modernize, standardize, and test
their IT systems at a fraction of the conventional time, cost, and risk.
In June of 2020, LogicFlow AG has already won 150’000 CHF from Venture Kick
Stage 3 for their unique software migration technology. LogicFlow is already
catering its software migration and testing capabilities to one of the major
Swiss banks, migrating over 100’000 lines of code at a record pace. The support
of Venture Kick has been decisive in shaping and bringing our offering to the
market.
Scientific advisor Prof. Fleisch shared his excitement over LogicFlow and their upcoming success: “I am proud to support LogicFlow since the very beginning. The team around Lucas Fiévet creates the code migration of tomorrow – a toolbox that every company in the digital space needs.” |
![]() |
![]() |
LogicFlow is dedicated to driving forward automation in software development. “We are grateful to our investors for their great support and confidence in LogicFlow,” |
With the pre-seed funding, LogicFlow will further develop its migration system
and expand its presence in the migration market. Further on, LogicFlow is
extending its technology to launch a plugin that will enable software developers
with smarter autocompletion to reduce development time and bugs.
For further information visit our
website
or follow us on
LinkedIn
.
Contact Information
LogicFlow AG
Lucas Fievet – CEO & Founder
Email:
[email protected]
Tel: +41 76 513 09 96
About LogicFlow
LogicFlow was launched in 2020 with the mission to drive automation in software
development that enables its customers to modernize their IT faster and focus
more on innovation. The technology behind LogicFlow has been developed since
2016 and is now delivering production-ready migration results for large corporations.
LogicFlow is a leading expert, both on the technology to automate software
development, as well as on the execution of large-scale software migration
and development projects.
About Venture Kick
The philanthropic initiative Venture Kick provides up to CHF 150,000 in seed funding to Swiss startups. In addition, it offers a well-structured entrepreneurial path towards building a winning business. Startups pitch to expert juries at three stages to obtain funding, gaining direct feedback and access to an international network of successful entrepreneurs and investors.
Since its launch in 2007, Venture Kick has supported 675 Swiss startup projects with 29.25 million francs. The program of financial support, training and network, has led to the creation of 519 companies and 6,967 jobs. Venture Kick alumni companies have attracted a total of 3.5 billion francs, and represent 54 companies ranked in the TOP 100 Swiss Startups 2019.
In 2020, Venture Kick will pay out 5 million francs to idea-stage startup projects to bring Swiss science to global markets. More information in the Venture Kick annual report.
The Venture Kick Foundation is supported by Gebert Rüf Stiftung, Ernst Göhner Stiftung, Hauser-Stiftung, André Hoffmann, Hansjörg Wyss, Martin Haefner, Igor Fisch, Fondation Pro Techno, ESA BIC Switzerland, Engagement Migros and Swisscom.
![]() |
FOLLOW
FOLLOW CONTACT US |
It’s no secret that migrating from AngularJS to the newer versions was a buzz for quite some time now in the tech world. Although the notion of “the newer the better” is relevant to Angular, still there are ongoing concerns if it’s actually worth it. There is always the question of how long it will take and how much will it cost. And we completely understand if you are undecided on the issue of migration.
But worry no more! We will guide you through things you need to know before making the final decision. First, you’ll discover in which ways newer versions of Angular are better than AngularJS. After that, we will give our recommendations on upgrading and introduce our amazing technology that will automate your migration that will make it fast and completely hassle-free!
Source GBKSOFT.com
Here are a few tips for you to make sure that the migration will be as painless as possible:
November 30, Zürich
If you haven’t visited Angular Materials documentation website yet, we will take you through the new visual updates! First, the Angular team has updated the homepage, added new colourful images on the component's page, and remade the guides page, and so much more!
Annie Wang, who is one of the people behind the Angular Components project, writes that the illustrations on the Material Design components inspired them with the aesthetic abstract design that referenced each component. The initial plan was to adapt the idea for material.angular.io, however, a few obstacles and requirements stood in the way. A major issue is the absence of the dedicated illustrator on the team. As for the requirements, the Angular Team wanted to make sure that images would be compact and clearly reference each individual component, as well as easily update images when the component’s appearance changed. Thus, the Angular Team decided to take upon themselves to build what they have envisioned from scratch.
The design of the components on the Angular Components is more of a realistic view rather than an abstract representation. They created “scenes” for every component to capture them the way they would be used. A technique named “screenshot testing” now helps to efficiently capture these components. It allows to capture an image of the page of the given URL and to compare it to the expected image. With the given technique, they can automatically generate up-to-date scenes for all the 35 components.
1) They have set up a route for each component which contains a “scene” using the actual material component
2) Created an end-to-end testing environment and took screenshots of each route with a protractor
3) Saved the screenshots instead of comparing them to an expected image
4) Loaded the screenshots from the site
This approach saves a lot of time and effort as whenever a component is going to be upgraded, all you need is to take new screenshots!
In fact, we use the screenshot automation for scenes at LogicFlow in our testing tool as well!
The team held a small hackathon to create each scene where they could share with their cool ideas. For instance, on the left - the button component, it displays all different styles and types of available buttons like FAB, icon, raised, etc. And on the right - we have the toggle component, where you can see the toggle in both states.
To conclude, we here at LogicFlow are excited for the new look of Angular Components as well as all the new updates, and we are sure you will love it as well! Take a look at the new website and let us know what you have enjoyed the most.
To read the original article from Angular Blog written by Annie Wang, click here
Hope you enjoyed our #MondayBlog on the latest news from the techno world. Be sure to follow us on LinkedIn and subscribe to our newsletter on our website, and we will make sure that you’ll not miss out on anything! Have a great and productive week and see you at the next #MondayBlog by LogicFlow!
1 | ng serve --hmr |
1 2 3 | resolutions: { webpack: "5.4.0" } |
1 | ng update @angular/cli @angular/core |
Checkout our job postings on the career page. Or contact us at [email protected].