Adding Angular to WebAPI site-part 41
First, I want to add an index.html file – to see the result.
For this, I add to the startup:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
//more code
app.UseDefaultFiles();
app.UseStaticFiles();
I also add an index.html into a wwwroot folder ( also created into the root)
You can see the modifications here: https://github.com/ignatandrei/InfoValutar/commit/4deb32528aee7b667f22a38c8e96899052cbfd4c
Now I want to compile the Angular application and add the index html generated by Angular to the wwwroot site
I create a powershell ( easy for me , because you can install dotnet tool powershell )
echo “starting build angular”
cd InfovalutarWebAng
npm i
ng build –prod –build-optimizer
cd ..$source= “InfovalutarWebAng/dist/InfovalutarWebAng/”
$dest= “InfoValutarWebAPI/wwwroot/”
echo “delete files”
Get-ChildItem -Path $dest -Include *.* -File -Recurse | foreach { $_.Delete()}
echo “copy files”
Get-ChildItem -Path $source | Copy-Item -Destination $dest
and put in Azure Devops pipelines
– powershell: |
cd InfoValutar
.\copyAng.ps1
displayName: copy angular site to web api
Now commit in GitHub (https://github.com/ignatandrei/InfoValutar/comAmit/5208036a4cb1da719692966880236dc33b1b2e74 )and waiting to see if it works
The error is : “The term ‘ng’ is not recognized as the name of a cmdlet, function, script file, or
The term ‘ng’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the
spelling of the name, or if a path was included, verify that the path is correct and try again.
“
Adding
npm i -g @angular/cli
It works!
Web site–Angular- part 40
Creating Angular app
ng new InfovalutarWebAng
Then customizing to add angular material
ng add @angular/material
and https://material.angular.io/guide/schematics#navigation-schematic
ng generate @angular/material:nav banks
Delete everyhing in app component ( without
<div class=”content” role=”main”>
add
<app-banks></app-banks>
)
See if it works. If yes, move the router outlet and footer to app-banks.
Now, I want to solve the CD and to run in a container for the people that do not have Angular installed – or do not want to.
Remember how it was for .NET Core , that I need just an Internet Connection , Docker and VSCode ? http://msprogrammer.serviciipeweb.ro/2019/12/04/debug-application-under-vscode-and-dockerpart-22/
Now it does not work – cannot load application because some bug in .NET Core . Why ? I have been going to .NET Core 3.1 and not updated the docker file…
ARG DOTNETCORE_VERSION=3.1
Now it loads – however, saying that the methid has not an implementation. Solving later.
Now going to
https://github.com/microsoft/vscode-dev-containers
to find same for Angular…
After some attempts, I have this files into .devcontainer
devcontainer.json
// For format details, see https://aka.ms/vscode-remote/devcontainer.json or the definition README at
// https://github.com/microsoft/vscode-dev-containers/tree/master/containers/alpine-3.10-git
{
“name”: “Angular”,
“dockerFile”: “DockerfileAng”,
// Uncomment the next line to have VS Code connect as an existing non-root user in the container.
// On Linux, by default, the container user’s UID/GID will be updated to match your local user. See
// https://aka.ms/vscode-remote/containers/non-root for details on adding a non-root user if none exist.
// “remoteUser”: “vscode”,// Uncomment the next line if you will use a ptrace-based debugger like C++, Go, and Rust
// “runArgs”: [ “–cap-add=SYS_PTRACE”, “–security-opt”, “seccomp=unconfined” ],
// Use ‘settings’ to set *default* container specific settings.json values on container create.
// You can edit these settings after create using File > Preferences > Settings > Remote.
“settings”: {
// This dev container does include /bin/bash if you prefer to use it instead of ash.
“terminal.integrated.shell.linux”: “/bin/ash”
},// Use ‘appPort’ to create a container with published ports. If the port isn’t working, be sure
// your server accepts connections from all interfaces (0.0.0.0 or ‘*’), not just localhost.
// “appPort”: [],// Uncomment the next line to run commands after the container is created.
// “postCreateCommand”: “uname -a”,// Add the IDs of extensions you want installed when the container is created in the array
// below. Note that some extensions may not work in Alpine Linux due to glibc dependencies
// in native code inside the extension. See https://aka.ms/vscode-remote/linux for details.
“extensions”: [],
“postCreateCommand”: “cd InfovalutarWebAng && npm i”,
“overrideCommand”:true,
“shutdownAction”: “stopContainer”
}
and DockerFileAng
#————————————————————————————————————-
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
#————————————————————————————————————-
FROM alpine:3.10# This Dockerfile adds a non-root user with sudo access. Use the “remoteUser”
# property in devcontainer.json to use it. On Linux, the container user’s GID/UIDs
# will be updated to match your local UID/GID (when using the dockerFile property).
# See https://aka.ms/vscode-remote/containers/non-root-user for details.
ARG USERNAME=vscode
ARG USER_UID=1000
ARG USER_GID=$USER_UID# Install git, bash, dependencies, and add a non-root user
RUN apk add –no-cache git bash libgcc libstdc++ \
#
# Create a non-root user to use if preferred – see https://aka.ms/vscode-remote/containers/non-root-user.
&& addgroup -g $USER_GID $USERNAME \
&& adduser -S -s /bin/bash -u $USER_UID -G $USERNAME $USERNAME \
# [Optional] Add sudo support for the non-root user
&& apk add –no-cache sudo \
&& echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME\
&& chmod 0440 /etc/sudoers.d/$USERNAMERUN apk add –update npm
RUN npm install -g @angular/cli
Now I can run in remote container and ng serve from remote container ( do not forget to be in Angular folder and forward port from VSCode !)
Last Commit info–GitHub and AzureDevOps–part 39
I was thinking that I need to see the date of last CD – who done what. For this, I need 2 things: to have a controller/gui to show the info and the CD process, via GitHub/AzureDevOps ,to take care of that.
For the part with code, the problem was pretty simple:
using Microsoft.AspNetCore.Mvc; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace InfoValutarWebAPI.Controllers { /// <summary> /// info about commit /// </summary> public class LastCommitInfo { /// <summary> /// comment latest commit /// </summary> public string LatestCommit { get; set; } /// <summary> /// last date of commit /// </summary> public DateTime DateCommit { get; set; } /// <summary> /// last author of commit /// </summary> public string LastAuthor { get; set; } } /// <summary> /// controller about info the application /// </summary> [ApiController] [ApiVersion("1.0")] [Route("api/v{version:apiVersion}/rates")] public class InfoController { /// <summary> /// info about latest commit /// </summary> /// <returns></returns> public LastCommitInfo GetLatestCommit() { return new LastCommitInfo() { LatestCommit = "{LatestCommit}", DateCommit = DateTime.ParseExact("{DateCommit}", "yyyyMMdd:HHmmss", null), LastAuthor = "{LastAuthor}" } ; } } }
What about the CD process ?
Well, this was cumbersome. To see ALL the environment variables, I used cmd /K set ( in command ) or Get-ChildItem Env: ( in powershell).
And I come with this:
A bash script to take the version
– bash: |
git log –format=’%s’ -1
git log –pretty=oneline | head -1
gitMessage=$(git log –format=’%s’ -1)
echo “##vso[task.setvariable variable=commitMessage;isOutput=true]$gitMessage”
displayName: Store commit message in variable
– powershell: .\modifyinfo.ps1
displayName: modify info
And a .ps1 powershell
$file = “.\InfoValutar\InfoValutarWebAPI\Controllers\InfoController.cs”
$date = Get-Date -Format “yyyyMMdd:HHmmss”
Get-ChildItem Env:
$author= $Env:BUILD_SOURCEVERSIONAUTHOR
$commitText = $env:BASH_COMMITMESSAGE
((Get-Content -path $file -Raw) -replace ‘{LatestCommit}’,$commitText -replace ‘{LastAuthor}’,$author -replace ‘{DateCommit}’ , $date ) | Set-Content -Path $file
(Get-Content -path $file -Raw)
The result can be seen at https://infovalutar.azurewebsites.net/api/v1.0/info
Infovalutar
And one hour passes...(This is the result of 1 hour per day auto-challenge as a full cycle developer for an exchange rates application)
( You can see the sources at https://github.com/ignatandrei/InfoValutar/ )
Exchange rates–what I have done in 37 hours–part 38
What I have create for now in 37 hours :
- A source control – https://github.com/ignatandrei/InfoValutar
- A plugin based software – you can use to load any kind of exchange rates, for anywhere , provided that you implement the interface – see implementation
- Tests for some of the code
- Deployment:
- An Azure WebAPP WebAPI deployment – https://infovalutar.azurewebsites.net/swagger/index.html
- A Docker container for WebAPI – https://hub.docker.com/repository/docker/ignatandrei/infovalutar
- A playground for Docker in the browser – https://labs.play-with-docker.com/?stack=https://raw.githubusercontent.com/ignatandrei/InfoValutar/master/PlayWithDocker/WebAPI.yml
- A SqlServer database – to store datas
- An Azure Function – https://azurefuncloaddata20191205080713.azurewebsites.net/ – to load data at time based cron intervals
- A GitHub action to compile ,run tests , – https://github.com/ignatandrei/InfoValutar/actions
- An AzureDevops CI + CD to do all 1-6 things +code coverage + deploy https://dev.azure.com/ignatandrei0674/InfoValutar/_build?definitionId=5&_a=summary
I did say it is a nice work for 37 hours of work, right ?
Infovalutar
And one hour passes...(This is the result of 1 hour per day auto-challenge as a full cycle developer for an exchange rates application)
( You can see the sources at https://github.com/ignatandrei/InfoValutar/ )
Software Year 2019 in review
This is what impressed me in 2019
- On 8 January https://blog.github.com/2019-01-07-new-year-new-github/
- On 21 January https://java.com/en/download/release_notice.jsp : Public updates for Oracle Java SE 8 released after January 2019 will not be available for business, commercial or production use without a commercial license.
- On 8 February Ie default browser
- On 12 February https://www.bleepingcomputer.com/news/security/windows95-v20-lets-you-play-doom-wolfenstein-3d-and-more/
- On 7 March Microsoft Calculator implementation
- On 13 March https://send.firefox.com/
- On 29 March https://www.redhat.com/en/blog/future-through-software-developers-red-hat-key
- On 3 April https://docs.microsoft.com/en-us/visualstudio/releases/2019/release-notes
- On 18 May https://arstechnica.com/gadgets/2019/05/microsoft-open-sources-algorithm-that-gives-bing-some-of-its-smarts/
- On 23 May https://blog.stephenwolfram.com/2019/05/launching-today-free-wolfram-engine-for-developers/
- On 24 May Photo to OCR to Excel
- On 2 June https://devblogs.microsoft.com/typescript/announcing-typescript-3-5/
- On 2 June https://blog.angular.io/version-8-of-angular-smaller-bundles-cli-apis-and-alignment-with-the-ecosystem-af0261112a27
- On 7 June https://techcrunch.com/2019/06/05/microsoft-and-oracle-link-up-their-clouds/
- On 11 June UIPath – with CoreWF
- On 11 June CoreWCF – community : https://www.infoq.com/news/2019/06/WCF-Decision/
- On 12 June Salesforce is buying data visualization company Tableau for $15.7B in all-stock deal
- On 24 June https://www.raspberrypi.org/blog/raspberry-pi-4-on-sale-now-from-35/
- On 25 July Oracle EF Core
- On 5 August https://mspoweruser.com/microsoft-will-disable-vbscript-in-internet-explorer-11-from-this-month/
- On 2 September https://www.oracle.com/database/technologies/appdev/dotnet/odtvscodequickstart.html
- On 11 September https://www.zdnet.com/article/java-finally-goes-all-in-on-open-source-with-the-release-of-jakarta-ee-8/
- On 14 October https://www.oracle.com/cloud/free/
- On 9 November TypeScript 3.7
- On 11 December https://techcommunity.microsoft.com/t5/Microsoft-Teams-Blog/Microsoft-Teams-is-now-available-on-Linux/ba-p/1056267
- On 11 December .NET Core 3.1
Friday Links 352
What I have done in 2019–and goals for 2020
In 2019
- I have learned
- .NET Core – up to the version 3.1
- Angular- up to the version 8.0
- Docker – up to the 19.3
- TypeScript –up to 3.7
- JavaScript frameworks for backend and mono-repo
- I have started
- To learn Azure
- InfoValutar – https://github.com/ignatandrei/InfoValutar
- Bingo – https://github.com/alexandru360/PresentationBingoCards/ with Alex Badita
- Coordinating automation work at the office ( I am TD at EA )
- Written this blog and series about
- Migrating from MVC 1.0 to .NET Core and Azure : http://msprogrammer.serviciipeweb.ro/category/exchange-rates/
- Creating mono – repo for JavaScript – backend and frontend: http://msprogrammer.serviciipeweb.ro/category/bingo/
- Become an MVP again https://mvp.microsoft.com/en-us/PublicProfile/4025203?fullName=Ignat%20Andrei
- Organizing 12 ADCES meetings – Bucharest meetup about .NET and programming technologies : https://www.meetup.com/Bucharest-A-D-C-E-S-Meetup/
- Speaking at various conferences about .NET Core and Angular – see my previous MVP track
For 2020 I want
- Keep learning new versions of .NET Core / Angular / TypeScript / Docker
- Start learn AI / ML so I can be proficient ( starting point my InfoValutar)
- Finish migrating InfoValutar to Azure
- Continuing ADCES
- Continuing blogging ( this blog!)
- Speak at conferences
- Doing good work at the office
- Starting again the video series about tools in 5 minutes – maybe separating in C# and general programming tools ?
- Become MVP again
Basically, the same thing as for this year.
Azure functions – final–part 37
So , I said, now just retrieve data – and put on database:
try
{
log.Info(“trying to save”);
ISave save = new SaveSqlServer(null);
await save.Save(data.ToArray());
}
catch(Exception ex)
{
log.Error($”ERROR !! {ex.Message}”);
}
This gives me a new whole error:
ERROR !! Could not load type ‘System.IAsyncDisposable’ from assembly ‘netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51’.
Ok. Coming from start: What I want ? To save recent data into the database and checking at regular times. How to do that ? Simple . Just call https://infovalutar.azurewebsites.net/api/v1.0/save/LoadAndSaveAll
Good. So this should be the code:
log.Info($”LOAD from website: {DateTime.Now}”);
Console.WriteLine(“————————!!”);
var url = “https://infovalutar.azurewebsites.net/api/v1.0/save/LoadAndSaveAll”;
var http = new HttpClient();
var data = await http.GetStringAsync(url);
log.Info($”obtaining data {data}”);
And … it works flawless! – For BNR – for ECB it shows just a record. That is somehow strange – the coding was almost the same
Now it is time to wrote some more tests -and to find if ECB is loading more than 1 record. Yes, it is.
Then the problem is when saving? Or when loading ?
I have the result of saving :
public class ResultsLoadBankData
{
public string Bank { get; internal set; }
public int NrRecords { get; internal set; }
public bool HasSuccess { get; internal set; }
public string ErrorMessage { get; internal set; }
}
And I modified to this
public class ResultsLoadBankData
{
public string Bank { get; internal set; }
public int NrRecordsLoaded { get; internal set; }
public int NrRecordsSaved { get; internal set; }public bool HasSuccess { get; internal set; }
public string ErrorMessage { get; internal set; }
}
Also , there were many other small modifications when loading data.
Infovalutar
And one hour passes...(This is the result of 1 hour per day auto-challenge as a full cycle developer for an exchange rates application)
( You can see the sources at https://github.com/ignatandrei/InfoValutar/ )
IAsyncEnumerable transformed to IEnumerable and making Azure Functions works- part 36
Last time I have had problems because of IAsyncEnumerable not be loaded from SystemRuntime. Decided to modify code to use instead Task<Ienumerable>
The code modifications were interesting
await foreach (var e in nbr.GetActualRates())
//versus
foreach (var e in await nbr.GetActualRates())
yield return exch;
//versus adding to a list and return the list
ret.Add(exch);
var data = await nbr.GetActualRates().ToArrayAsync();
//versus
var data = (await nbr.GetActualRates()).ToArray();
All in all, not so difficult.Code changes at https://github.com/ignatandrei/InfoValutar/commit/d2744dd0cc194c6e63c7efc2f262ec1b233bde7c
To test in production, it does not help that AzureDevops is taking 7 minutes. Trying in the meantime to setup AzureDevOps on my PC.
In Azure Function – the same error occurred.
Ok . Now trying to see if something smaller can be possible. Rather to load every plugin to give information, maybe I can load just the plugins directly.
Cannot bind parameter ‘log’ to type ILogger
Apparently, a known issue for package hell . Reading
https://docs.microsoft.com/en-us/sandbox/functions-recipes/logging?tabs=csharp
Commuting to TtraceWriter
Now deployng from Visual Studio =>error: System.IO.FileNotFoundException: Could not load file or assembly ‘netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51’
Re-doing via CI – AzureDevOps : WORKS!
Infovalutar
And one hour passes...(This is the result of 1 hour per day auto-challenge as a full cycle developer for an exchange rates application)
( You can see the sources at https://github.com/ignatandrei/InfoValutar/ )