Category: Angular

Literary Awards–part 3–data

Part 1: http://msprogrammer.serviciipeweb.ro/2018/10/08/literary-awardspart-1/

Part 2: http://msprogrammer.serviciipeweb.ro/2018/10/15/literary-awardspart-2/

Part 3: http://msprogrammer.serviciipeweb.ro/2018/10/22/literary-awardspart-3/

Part 4: http://msprogrammer.serviciipeweb.ro/2018/10/29/literary-awardspart-4/

Part 5: http://msprogrammer.serviciipeweb.ro/2018/11/05/literary-awardspart-5/

 

The data – this was the difficult part. As I said, I wanted the data to be local – but how can I put the first time ? And where ? I cannot be cookie, since the authors are a large database for cookies…

There are 3 options : LocalStorage, WebSql and IndexedDB . You can read about those at https://nolanlawson.com/2015/09/29/indexeddb-websql-localstorage-what-blocks-the-dom/ . I choose LocalStorage because it was simpler – however, this is making the startup of the application slower!

Now, how can I store the data ?  For me, a database with select it was fine – but can I find one that works in the browser ? And with javascript ? Apparently, yes! There is a port from C to js of SQLite – https://github.com/kripken/sql.js/ . That means , I can have a SQLIte database and access via Select. Add I can persist too – see https://github.com/kripken/sql.js/wiki/Persisting-a-Modified-Database .

 

With all those, now I am ready to have the Nobel authoirs in my application – but how can I introduce to my application ? The list exists on Wikipedia( https://en.wikipedia.org/wiki/List_of_Nobel_laureates_in_Literature)  and at Nobel site (https://www.nobelprize.org/prizes/literature/) . How can I load those into my SQLite LocalStorage database ?

Here comes another pet project of mine, stankins  . With this I can transform the wikipedia page into this:


db.run("INSERT INTO tableAuthors (Year,Laureate,Languages,Citation,Genres,PictureUrl,LaureateFullWiki,name) VALUES (?,?,?,?,?,?,?,?)", [

"1901",

"Sully Prudhomme",

"French",

'"in special recognition of his poetic composition, which gives evidence of lofty idealism, artistic perfection and a rare combination of the qualities of both heart and intellect"[12]',

"poetry, essay",

"//upload.wikimedia.org/wikipedia/commons/thumb/3/39/Sully-Prudhomme.jpg/75px-Sully-Prudhomme.jpg",

"https://en.wikipedia.org/wiki/Sully_Prudhomme",

"Sully_Prudhomme"

]);

db.run("INSERT INTO tableAuthors (Year,Laureate,Languages,Citation,Genres,PictureUrl,LaureateFullWiki,name) VALUES (?,?,?,?,?,?,?,?)", [

"1902",

"Theodor Mommsen",

"German",

'"the greatest living master of the art of historical writing, with special reference to his monumental work, A History of Rome"[13]',

"history, law",

"//upload.wikimedia.org/wikipedia/commons/thumb/e/e9/T-mommsen-2.jpg/75px-T-mommsen-2.jpg",

"https://en.wikipedia.org/wiki/Theodor_Mommsen",

"Theodor_Mommsen"

]);

Obvious, it is not perfect – but it works!

What can I do with upgrades * because , obvious, each year I should add the Nobel authors ? Nothing simpler: I will modify the name of the database with the application version from package.json

 

In environement.ts ( and in prod)


VERSION: require('../../package.json').version

In the typescript class:


public version: string = environment.VERSION;

Finally , in the create database


this.dbPers = new SQL.PersistentDatabase(

"nobel_v"+this.version,

async function(sender) {

// Initial creation of database if not found

self.createDatabase(sender).then(()=>{

sender.save();

});

},

function(e) {

// Initialization of existing database failed

alert("database failed" + e);

}

);

The source code is at github:https://github.com/ignatandrei/LiteraryAwards

Literary Awards–part 2–design

Part 1: http://msprogrammer.serviciipeweb.ro/2018/10/08/literary-awardspart-1/

Part 2: http://msprogrammer.serviciipeweb.ro/2018/10/15/literary-awardspart-2/

Part 3: http://msprogrammer.serviciipeweb.ro/2018/10/22/literary-awardspart-3/

Part 4: http://msprogrammer.serviciipeweb.ro/2018/10/29/literary-awardspart-4/

Part 5: http://msprogrammer.serviciipeweb.ro/2018/11/05/literary-awardspart-5/

 

One of the first problem that I was design. How to make a design that works on mobile and web and desktop ? Nowadays, the standard seems to be a menu on the left , that will be hidden when the mobile is rendering  . Also , this menu has three lines that allows to expand / collapse.

There are several resources at https://angular.io/resources .

I have tested all the resources with Window Resizer from Chrome and I was impressed by I was impressed by http://akveo.com/ngx-admin .

I have found the  empty starter kit (https://github.com/akveo/ngx-admin/tree/starter-kit ) and I started to modify

 

There was a learning curve here:

The search –  I did not know how to make the search  that was provided , until I found something that was called “

NbSearchService” – always search for a service …

It was a while until a figured how to add a new page to the existing pages ( and now I copy /paste)

I ended up with a bunch of images (https://github.com/akveo/ngx-admin/tree/starter-kit/src/assets/images )and other resources that were not needed

 

All in all, I think that it is more convenient to choose something simpler and not choose a big framework.

The design was pretty simple: Add links on the right to Nobel prize, Booker prize, others and list the authors / books.

And a search will be convenient to find fast the authors on the main page.

But about the data , next time

The source code is at github:https://github.com/ignatandrei/LiteraryAwards

Literary Awards–part 1–start

Part 1: http://msprogrammer.serviciipeweb.ro/2018/10/08/literary-awardspart-1/

Part 2: http://msprogrammer.serviciipeweb.ro/2018/10/15/literary-awardspart-2/

Part 3: http://msprogrammer.serviciipeweb.ro/2018/10/22/literary-awardspart-3/

Part 4: http://msprogrammer.serviciipeweb.ro/2018/10/29/literary-awardspart-4/

Part 5: http://msprogrammer.serviciipeweb.ro/2018/11/05/literary-awardspart-5/

 

I was curious to make a project for web and mobile.

The constraints:

1. database just on local, not on a central repository.

2. All with Javascript( OK, TypeScript).,

3. To work on web , mobile, desktop without changing something

 

The purpose of the project was to list the Literary awards – Nobel, Booker, others. ( I maintain myself a list of best books at http://serviciipeweb.ro/propriu/best-of/ )

You can see the final result at ( It is missing the desktop application – but – can you help me with that  – Electron ):

Site Web:https://ignatandrei.github.io/LiteraryAwards/

Google Play :https://play.google.com/store/apps/details?id=com.msprogrammer.com

Amazon :https://www.amazon.com/AOM-Literary-Awards/dp/B07HPFSZ4C/

The source code is at github:https://github.com/ignatandrei/LiteraryAwards

 

In the next blog posts I will show how I made this application – and problems / features / ideas. .

Angular , CORS and .NET Core SignalR

I have written a .NET Core  SignalR + Agular Observable of continously delivering the data. (http://msprogrammer.serviciipeweb.ro/2018/06/25/net-core-signalr-hub-angular-observable/ )

The setup is that .NET WebAPI resides in Visual Studio Project ( .sln. .csproj) and Angular Project is separate in another folder.

There are some settings in the development to be done in order to work

  1. Setting CORS in .NET Core  ( not really necessary- see below)
  2. Usually you will not need to set CORS in .NET Core if you plan to deliver Angular and .NET Core in the same site.

    But anyway, to allow anyoneto call you API , you will do something like this :

    services.AddCors();
    services.AddMvc();
    //...
     app.UseCors(it =>it.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
    //if (env.IsDevelopment())
    //{
    //    app.UseDeveloperExceptionPage();
    //}
    
    

    Of course, you can set for a domain, a header , and so on

    Also , do not forget to handle CORS errors – either by commenting the developer exception page, either by using a custom middleware, like https://blog.jonathaneckman.io/handling-net-core-web-api-exceptions-with-an-aurelia-fetch-interceptor/

  3. Setting  CORS like it does not exists for Angular
  4. For this:

    In the Angular environment.ts put those:

    export const environment = {

    production: false, //put also in the prod

    urlAPI:’/’

    }

    • In production: deliver AOT Angular compiled in the same folder with the .NET
    • This will ensure that , when you send the Angular AOT build with .NET Core WebAPI in the same site, it will work. NO CORS involved 😉

    • In development: This mean Angular ng server intercepting  calls

    Then create a file named proxy.conf.js and put this to redirect:

    const PROXY_CONFIG = [
        {
          context: [
              "/employees",
              "/api",                
          ],
          target: "http://<url to the .NET Core API>/",
          secure: false,
          "changeOrigin": true,
          "logLevel": "debug",
          ws: true
        }
    ]
    module.exports = PROXY_CONFIG;
    
    

    Then run:

    ng serve –proxy-config proxy.conf.js –open

  • Setting SignalR for Angular in development
  • See ws: true in previous proxy.conf.js ? That is all, if you run

    ng serve –proxy-config proxy.conf.js –open

    From unstructured data to application

    Imagine that you have this kind of texts:

    Alpert of Metz – 11th-century – France – Medieval writers
    Aimoin of Fleury – c. 960 – c. 1010 – France – Medieval writers
    Amulo Lugdunensis (Archbishop of Lyon) – 9th-century – France – Medieval writers
    Amulo Lugdunensis (Archbishop of Lyon) – 9th-century – France / Carolingian Empire – Medieval writers
    Andrew of Fleury – 11th-century – France – Medieval writers
    Angelomus of Luxeuil – 9th-century – Francia / France – Medieval writers

    Vitsentzos or Vikentios Kornaros or Vincenzo Cornaro – c. 1553 – c. 1614 – Kingdom of Candia / Crete / Greece – Renaissance

    Adrianus of Tyre – c. 113 – c. 193 – Greece / Roman Empire – Ancient & Classical writers

    How transform this unstrcutured data to make an application that search like in the picture below ( just the R from CRUD )?

    Detailing  the tools:

    1.  Transforming data: Excel + VBA – to parse from the text the name, country / countries , years period  movement and generate insert  /stored procedurees call

    2. Storing+ retrieving data: Sql Server – creating tables and stored procedures to insert / retrieving data

    3. Acessing data: .NET Core – to make WebAPI to export as WebAPI HTTP endpoints t

    4. Display data:

    5. Deploy:

    • RedfHat OpenShift to deploy site
    • Azure to have sql server on the web

    Hours or work ~ 20 . And hey, it works!

    .NET Core SignalR Hub+ Angular Observable

    TL;DR: Deliver all the table content continuously paginated to the browser with .NET Core and Angular


    Long Description:

    I was thinking that delivering paginating data is kind of lame. Why should I , for seeing the whole data, should keep pressing next page / or scrolling  down ? I understand that on the server it is necessary to do this – but on the client ?

    And I was thinking – what about Observables in Angular  , combined with SignalR ? Those observables could obtain data every time – and SignalR is pushing cotinously, until it arrives at the end of the data.

    Done with talking –  let’s show some code:

    We have an Employee classs

    public class Employee
        {
            public string Name { get; set; }
            public int Id { get; set; }
    
        }
    

    code

    and we are feeding with data in a DALEmployee

    public class DalEmployee
        {
            public int FindCountEmployees(string name)
            {
                return ((name ?? "").Length + 1) * 10;
            }
    
            public async Task<Employee[]> FindEmployee(int pageNumber, int pageSize, string name)
            {
                await Task.Delay((pageNumber + 1) * 1000);
                var ret = new Employee[pageSize];
                int startNumber = (pageNumber - 1) * pageSize;
                for (int i = 0; i < pageSize; i++)
                {
                    var e =new Employee();
                    e.Id = startNumber + i;
                    e.Name = e.Id + "employee ";
                    ret[i] = e;
                }
    
                return ret;
            }
        }
    

    We have SignalR that delivers continously the data via a Hub that is connected to an URL

    //do not forget  services.AddSignalR().AddJsonProtocol()  ;
                app.UseSignalR(routes =>
                {
                    routes.MapHub<MyHub>("/employees");
                })
    

    and delivers all data continuously

     public class MyHub: Hub
        {
           
            public override async Task OnConnectedAsync()
            {
                Console.WriteLine("!!!!connected");
                await Task.Delay(1000);
            }
            public ChannelReader<Employee[]> GetEmps(string name)
            {
                var channel = Channel.CreateUnbounded<Employee[]>();
                _ = WriteItems(channel.Writer, name); //it not awaits!
    
                return channel.Reader;
            }
    
            private async Task WriteItems(ChannelWriter<Employee[]> writer, string name)
            {
                var dal = new DalEmployee();
                var nr = dal.FindCountEmployees(name);
                int nrPages = 10;
                for (int i = 0; i < nr / nrPages; i++)
                {
                    var data = await dal.FindEmployee(i+1, nrPages, name);
                    await writer.WriteAsync(data);
                }
    
                writer.TryComplete();            
            }
    

    And this is all that is required on the .NET Core side

    For the Angular Part

    We have a hubconnectionbuilder that connect to the hub

    export class MydataService {
    
      h:HubConnection;
      constructor(private http: HttpClient) { 
        this.h= new HubConnectionBuilder()
          .withUrl(environment.urlAPI + "/employees")
          .withHubProtocol(new JsonHubProtocol())
          //.withHubProtocol(new MessagePackHubProtocol())
          .build();
          window.alert('start');
        this.h.start()
        .catch((t) => window.alert(1));
      }
      
      
    }
    

    and a observable that returns the values

    
    
      public getAllEmpsStream(name:string): Observable<Employee[]>{
        
        const subject = new Subject<Employee[]>();
        this.h.stream<Employee[]>("GetEmps",name).subscribe(subject);
        return subject.asObservable();
    
      }
    
    

    The code on the component is aggregating the values into an array

    findEmployees(){
        this.load=true;
        this.service
          
          .getAllEmpsStream(this.nameEmp)
          //.getEmps(this.nameEmp)
          .pipe(finalize(() => this.load=false))
          .subscribe(it  => {
            
            //window.alert(it.length);
            this.emp.push(...it);
    
          });
    
      }
    

    And that is all. All the values are returned page after page without the need of human intervention…

    Angular , .NET Core, IIS Express and Windows Authentication

    2 years ago I have written about .NET Core Windows Authentication :http://msprogrammer.serviciipeweb.ro/2016/09/26/asp-net-core-and-windows-authentication/ 

    The idea was that for Windows authentication this is mandatory in Web.Config:

    forwardWindowsAuthToken="true"

    Now I want to show how to achieve the same in  IIS Express .NET Core as backend and Angular for front end

    For .NET Core / IIS Express

    1. Configure IISExpress : https://www.danesparza.net/2014/09/using-windows-authentication-with-iisexpress/ 

    On short: find %userprofile%\documents\iisexpress\config\applicationhost.config  or %userprofile%\my documents\iisexpress\config\applicationhost.config  and put

    <windowsAuthentication enabled="true">
        <providers>
            <add value="Negotiate" />
            <add value="NTLM" />
        </providers>
    </windowsAuthentication>

    2.  On your project: Put in launchSettings.json :

    “windowsAuthentication”: true,
    “anonymousAuthentication”: false,

    3.  Optional: To verify add an Action that returns

    (this.User?.Identity?.Name ?? "Not ad enabled")

    For Angular

    return this.http.get(url,{
    withCredentials: true
    });

    4. ASP.NET Core 2.1
    https://github.com/aspnet/Home/releases/tag/2.1.0

    Windows authentication is not enabled after creating project with the Windows authentication option selected
    When creating a template with Windows authentication, the settings to enable Windows authentication in launchSettings.json are not applied.
    Workaround: Modify launchSettings.json as follows:

    “windowsAuthentication”: true,
    “anonymousAuthentication”: false,

    Andrei Ignat weekly software news(mostly .NET)

    * indicates required

    Please select all the ways you would like to hear from me:

    You can unsubscribe at any time by clicking the link in the footer of our emails. For information about our privacy practices, please visit our website.

    We use Mailchimp as our marketing platform. By clicking below to subscribe, you acknowledge that your information will be transferred to Mailchimp for processing. Learn more about Mailchimp's privacy practices here.