Showing posts with label Reactive Extensions. Show all posts
Showing posts with label Reactive Extensions. Show all posts

Tuesday, July 10, 2018

A18–Building App using Angular and ASP.NET Core 2.1–Reactive Forms, Submitting data

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16, A17 Github Repo

So I was able to accomplish following

1. Created classes to collect data from Form into Model for Shipping and Payment Pages.

2. Create CheckoutService to call Checkout controller methods

3. Created Controller methods for insert of shipping info and payment info

That’s all I have for today. Checkout latest changes on github and website.

Sunday, July 8, 2018

A17–Building App using Angular and ASP.NET Core 2.1–Reactive Forms Validation

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15, A16 Github Repo

I am currently watching Angular Reactive Forms course on Pluralsight by Deborah Kurata. I like Reactive Forms.

Today, I added form validation to shipping info page and payment info page.

image

image

Couple of things to note regarding behavior

1. Validation occurs as soon as you tab our or touch a control.

2. If you click on Next button then validation messages will be shown

3. Simple Regex pattern matching used for phone, card number, security code

4. Added dropdown for selecting card type and expiration month and year

5. Custom group validation implemented for validation Expiration month.

image

Special thanks to Loiane Groner for sharing code @ repo to show validation on button click. This trick and using a method to display validation messages saved a ton of repetitive code for me. I like it a lot.

Thanks to Debora Kurata for sharing code @ repo.

That’s all I have for today. Checkout latest changes on github and website.

Tuesday, June 26, 2018

A13–Building App using Angular and ASP.NET Core 2.1–Updating Shopping Cart Quantity

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12 Github Repo

Today’s post is going to be brief. I added following functionality to Shopping Cart page.

When you increase quantity of any given product then,

1. Order sub total should get updated.

2. Order Quantity should be updated.

3. Cart total should be updated.

Since there is no database backend, I have to add extra logic to account for persistence. For example, to simulate accurate quantity and amount post deletion, I had to write custom server side logic. This is unnecessary once data store is in place.

image

After increasing quantity order sub total is updated.

image

There is one issue I am running into and that is when using ngModelChange on input element, the change event is firing twice which seems like bug to me or I am doing something wrong (I think later to be true).

That’s all for today, see ya next time.

Thursday, June 21, 2018

A10–Building App using Angular and ASP.NET Core 2.1–Services, Events and Cross Component Communication

This post is a part of a series of posts that I am writing as I am building an app using Angular and ASP.NET Core 2.1. Links to previous posts –> A1, A2, A3, A4, A5, A6, A7, A8, A9 Github Repo
Today, I was able to accomplish few things,
1. Added Shopping service that adds product and updates shopping cart
2. Established cross component communication via Shopping Service (Home Component –> Add To Cart –> Updates Shopping Cart
3. Created API for adding and getting products from ShoppingCart Controller. I am returning hard coded products and hence you will always see two shown at the top right.
Right now I didn’t wanted to create any database backend. I want to just make sure client server interaction is in sync. Once I like how everything is structured then I will invest time into adding database layer. Below is code for Shopping Service.
import { Injectable, Inject } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Product } from '../product/product';
import { catchError, map, tap,last } from 'rxjs/operators';
import 'rxjs/add/observable/throw';
import { of } from 'rxjs/observable/of';
import { Observable } from 'rxjs/Observable';
const httpOptions = {
  headers: new HttpHeaders({
    'Content-Type': 'application/json'
  })
};
@Injectable()
export class ShoppingService {

  private _baseUrl: string;
  private cartQuantitySource = new BehaviorSubject(0);
  currentCartQuantity = this.cartQuantitySource.asObservable();

  private _addProductToShoppingCart: string = "api/ShoppingCart/Add/";
  private _getProductsFromShoppingCart: string = "api/ShoppingCart/Products";
  constructor(private _http: HttpClient, @Inject('BASE_URL') baseUrl: string) {
    this._baseUrl = baseUrl;
    this.updateCartQuantity(); 
  }

  updateCartQuantity() {
    this._http.get<Product[]>(this._baseUrl + this._getProductsFromShoppingCart).subscribe(products => {
      this.log(`getting products from shopping cart`);
      this.cartQuantitySource.next(products.length);
    });
  }

  addProductToCart(product: Product) {
    this._http.post(this._baseUrl + this._addProductToShoppingCart + product.id, product, httpOptions).subscribe(x => {
      this.log(`added Product To Shopping Cart`);
      this.updateCartQuantity();
    });    
  }

  private handleError<T>(operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.log(error); //log to console instead       
      this.log(`${operation} failed: ${error.message}`);
      return Observable.throw(error || 'Server error');
    };
  }
  private log(message: string) {
    console.log("Shopping Service " + message);
  }
}

One of the things, I am not liking is how api urls are hard coded as strings. This is something I want to improve upon. I will put them inside an injectable service which has all the urls.
Next thing I want to learn is authentication and authorization with ASP.NET Core.

Wednesday, December 6, 2017

Real Time monitoring Windows Event Logs using Reactive Extensions

In this post, I want to demonstrate how I have used Reactive Extensions to monitor Windows Event Log entries as they get added to Event Logs by a specific provider.  The main piece that enables us to do this is Tx.All a single nuget package that exposes event log events as observables using Reactive Extensions. I will create two console projects, one for monitoring event logs and another to generate Event Logs.   

Part 1 – Monitoring Console App

Create a blank .NET console project (do not select .NET core).  Then Install Tx.All Nuget Package and your packages.config file should look as shown below.


<?xml version="1.0" encoding="utf-8"?>
<packages>
  <package id="System.Reactive" version="3.1.1" targetFramework="net47" />
  <package id="System.Reactive.Core" version="3.1.1" targetFramework="net47" />
  <package id="System.Reactive.Interfaces" version="3.1.1" targetFramework="net47" />
  <package id="System.Reactive.Linq" version="3.1.1" targetFramework="net47" />
  <package id="System.Reactive.PlatformServices" version="3.1.1" targetFramework="net47" />
  <package id="System.Reactive.Windows.Threading" version="3.1.1" targetFramework="net47" />
  <package id="Tx.All" version="2.1.1" targetFramework="net47" />
  <package id="Tx.Core" version="2.1.1" targetFramework="net47" />
  <package id="Tx.SqlServer" version="2.1.1" targetFramework="net47" />
  <package id="Tx.Windows" version="2.1.1" targetFramework="net47" />
  <package id="Tx.Windows.TypeGeneration" version="2.1.1" targetFramework="net47" />
</packages>

Then use the following code to query specific provider inside Event Log. We are interested into Application event logs and our provider is ConsoleEventLogGenerator.

using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Reactive.Linq;
using System.Text;
using System.Threading.Tasks;
using Tx.Windows;

namespace ConsoleMonitor
{
    class Program
    {
        static void Main(string[] args)
        {
            IObservable<EventRecord> evtx = EvtxObservable.FromLog("Application");
            IDisposable d = evtx.Where(y => y.ProviderName == "ConsoleEventLogGenerator").Subscribe(e => {
                Console.WriteLine(e.FormatDescription());
            });

            Console.WriteLine("Waiting for Event Log entry for provider - \"ConsoleEventLogGenerator\"");
            Console.Read();
        }
    }
}

Now we will create another console project to create event in the Event Log. 

Part 2 – Create another Console Project.

In the following code we are creating lots of events log entries and our source is ConsoleEventLogGenerator. This string has to match the string shown in the earlier section.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleEventLogGenerator
{
    class Program
    {
        static void Main(string[] args)
        {
            EventLog log = new EventLog("Application");
            log.Source = "ConsoleEventLogGenerator";

            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(1000);
                log.WriteEntry("test " + i);
            }
        }
    }
}

In the next section you will fire up both the application side by side and you will see events showing up in real time.

image

I have created a simple console app like this to monitor event log when I am debugging a certain application that writes everything to event log.  Seeing output in real time helps a lot in debugging.