Author Archives: geoff

Angular – Using Form Builder

We can use formbuilder rather than declaring each component and form group new ourselves.

This relies on us adding the import “FormBuilder from @angular/forms

We then use this by utilizing the constructor:


import { Component, OnInit } from '@angular/core'
import { FormGroup, FormControl, FormBuilder } from '@angular/forms'

export class OurComponent implements OnInit {
   customerForm: FormGroup;
   customer: Customer = new Customer();

   constructor(private fb: FormBuilder) { }

   ngOnInit(): void {
      this.customerForm = this.fb.group({
         firstName: 'default'
      });
   }
}

or instead of “firstName: ‘default'” you could use “firstName: {value: ‘default’, disabled: false}” this allows you to pass an initial state to the item. Maybe more importantly we can use an array syntax instead which allows us to pass in validators i.e. firstName: [‘default’, [Validators.required]]. In this final example we are using one of the angular built in validators but we can also define and use our own. As you can see this can be an array of multiple comma separated validators.

Angular – Template and Reactive Forms

There are two types of form you can use with Angular “Template driven” and “Reactive” (also known as “Model driven”).

Template driven forms rely on the html to deal with the majority of the form building. See below for a Template driven form. This binds a property from our component class to the value of the input element. You must have a name element in order for this to work effectively. #firstNameVar is the template reference variable to access the form control instance this allows for some error validation. Angular does a lot of our work for us in the template driven approach however it is less flexible. NgModel gives us the two way binding.

 
 
Please enter first name.
 
 

The second type of form in Angular is the Reactive form. In this approach we create the form module (which angular deals with under the hood in the Template based approach.

Component:

import { Component, OnInit } from '@angular/core'
import { FormGroup, FormControl } from '@angular/forms'

export class OurComponent implements OnInit {
   customerForm: FormGroup;
   customer: Customer = new Customer();

   ngOnInit(): void {
      this.customerForm = new FormGroup({
         firstName: new FormControl('default')
      });
   }
}

Remember to add ReactiveFormsModule to the declarations of the Module!

Creating the Reactive Form:

 

 

 

We can now use the formgroups get method i.e. customerForm.get(‘firstName’).valid in the html.

XML Config File Load Angular

config.json file:

This is the file we want to load information from. This needs to be globally accessible so will need to be put in a directory under assets.

{
    "apiUrl":"http://localhost:9000",
    "readerUrl": "http://localhost:8088"
}

main.ts file:

This loads are new config file.

import {Config} from "./app/app.config";

Config.loadInstance('assets/config/config.json')
    .then(() => {
        platformBrowserDynamic().bootstrapModule(AppModule);
    });

app.module.ts file:

This gets the instance and provides it.

import {Config} from "./app.config";

providers: [
        {provide: Config, useFactory: () => Config.getInstance('assets/config/config.json')},
]

app.config.ts file:

This is the main config code.

import {Injectable} from "@angular/core";

@Injectable()
export class Config {

    private static cache = {};

    constructor(private data: any) { }

    public static loadInstance(jsonFile: string) {
        return new Promise((resolve, reject) => {
            var xobj = new XMLHttpRequest();
            xobj.overrideMimeType("application/json");
            xobj.open('GET', jsonFile, true);
            xobj.onreadystatechange = () => {
                if (xobj.readyState == 4) {
                    if (xobj.status == 200) {
                        this.cache[jsonFile] = new Config(JSON.parse(xobj.responseText));
                        resolve();
                    }
                    else {
                        reject(`Could not load file '${jsonFile}': ${xobj.status}`);
                    }
                }
            }
            xobj.send(null);
        });
    }

    public static getInstance(jsonFile: string) {
        if (jsonFile in this.cache) {
            return this.cache[jsonFile];
        }
        throw `Could not find config '${jsonFile}', did you load it?`;
    }

    public get(key: string) {
        if (this.data == null) {
            return null;
        }
        if (key in this.data) {
            return this.data[key];
        }
        return null;
    }
}

SharePlex Oracle Replication

SharePlex Replication

SharePlex is a potential replacement for Oracle Advanced Replication or Oracle Streams Replication.  Now that both these have been removed from Oracle 12C its time to consider alternatives.  Oracle Gold Gate is a possible but it’s expensive and complex.  SharePlex seems to have a lot going for it in terms of simplicity and ability to use it across different database environments.

[table id=1 /]

Sources:
https://support.quest.com/technical-documents/shareplex/8.6.4/installation-guide

Useful SharePlex Commands:
• startup, shutdown
• all configuration commands relating to an active configuration
• all parameter commands except list param
• start capture
• stop capture
• abort capture
• truncate log

Updating DB Scaffold

To update the scaffold you need to set the force flag:

Scaffold-DbContext "Server=;Database=;user id=;password=;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=False" Microsoft.EntityFrameworkCore.SqlServer -f -OutputDir Models

note the -f

Entity Framework Scaffold DBContext (ASP.NET Core)

Steps:

– Install EF:

Install-Package Microsoft.EntityFrameworkCore.SqlServer

Install-Package Microsoft.EntityFrameworkCore.Tools –Pre
Install-Package Microsoft.EntityFrameworkCore.Design
Install-Package Microsoft.EntityFrameworkCore.SqlServer.Design

– Add to project.json

 "tools": {
   "Microsoft.EntityFrameworkCore.Tools.DotNet": "1.0.0-preview3-final",
   "Microsoft.AspNetCore.Razor.Tools": "1.0.0-preview2-final",
   "Microsoft.AspNetCore.Server.IISIntegration.Tools": "1.0.0-preview2-final"
 },

– From “NuGet Package Manager” then “Package Manager Console”

Scaffold-DbContext "Server=;Database=;user id=;password=;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=False" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

– Update appsettings.json to include the connection string..

  "Data": {
    "DefaultConnection": {
      "ConnectionString": "Server=devsql01;Database=nasr_scratch;user id=dev;password=Automation15;Trusted_Connection=True;MultipleActiveResultSets=true;Integrated Security=False;"
    } 
  },

– Add the DbContext to the Startup.cs using the connection string..

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            // Add framework services.            
            services.AddMvc();
            services.AddDbContext(
                o => o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
        }

Update the Context:

public class MyContext : DbContext
{
    public MyContext(DbContextOptions options)
      :base(options)
    { }
}

– Create your controller. For Instance; BulkTagCreationController. You can now reference the context using DI.

    [Route("api/configuration/[controller]")]
    public class BulkTagCreationController : Controller         
    {
        public readonly nasr_scratchContext _context;

        public BulkTagCreationController(nasr_scratchContext context)
        {
            _context = context;
        }