Thursday, April 5, 2018

Ctrl-Click on a TypeScript type in an import to go to the file that has the type in Visual Studio Code 1.17.2.

nice.

Use just Headers and not HttpHeaders with HttpClient in an Angular 4 application.

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Configuration } from '../../configuration';
import { Http, Headers, RequestOptions, Response } from '@angular/http';
import { HttpClient } from '@angular/common/http';
import { President } from '../models/president.model';
import { PresidentialContract } from '../contracts/presidential.contract';
@Injectable()
export class PresidentialService implements PresidentialContract {
   constructor(private http: Http, private httpClient: HttpClient, private configuration:
         Configuration) { }
   
   getPresidents():Observable<Array<President>>{
      let route: string = this.configuration.routeToApi + "api/president";
      return this.httpClient.get<Array<President>>(route,{});
   }
   
   setPresidents(presidents:Array<President>):Observable<any>{
      let route: string = this.configuration.routeToApi + "api/president";
      let headers = new Headers({ 'Content-Type': 'application/json' });
      let options = new RequestOptions({ headers: headers });
      return this.http.put(route, presidents, options).map((response: Response) =>
            <Boolean>response.json());
   }
}

 
 

I guess to solve the problem mentioned here this...

let headers = new Headers({ 'Content-Type': 'application/json' });

 
 

...could become...

let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });

 
 

This has a little cheatsheet on the Content-Type possibilities. This has a cheatsheet of what all of the request fields beyond and including Content-Type are. I guess if we wanted to get some XML back from our requests our headers could be like so:

let headers = new Headers({ 'Accept': 'application/xml',
      'Content-Type': 'application/json' });

 
 

The order of the headers should not matter.

A double pipe in JavaScript can be used like the ?? null coalescing operator in C#.

var whatever = function(yin) {
   return yin.yang || new Yang();
}

If the fat arrow inside of a .then in TypeScript has only the one line for returning something, you don't need to wrap the line in curly braces or use the return keyword.

This...

.then(x => new Whatever(x));

 
 

...does the same thing as this:

.then(x => { return new Whatever(x); });

 
 

Addendum 4/6/2018: Remember if you do this simplification trick when newing up an object with curly braces that you need to wrap the curly braces in parenthesis. So this...

.then(x => { return {'foo':'bar','baz':'qux'} });

 
 

...becomes...

.then(x => ({'foo':'bar','baz':'qux'}) );

NgRx selectors

In a Redux selector in an Angular application one hands in at least one function that returns a stateful object and then gets back a function that returns an object like so:

import { DataContext, MyStateModel } from '../data-models';
import { createSelector } from '@ngrx/store';
 
export const getStuff = function (state: DataContext) {
   return state && state.myState ? state.myState : new MyStateModel();
};
 
export const getSpecificStuff = createSelector(
   getStuff,
   (x: MyStateModel) => {
      return x.mySpecificState;
   }
);

 
 

The last argument defines the shape of what should be handed back. The preceding argument in the example above is a function returning state, but it should be noted that there could be n number of these handed in before the definition for what should be returned including other selectors. You may hand selectors in as the leading arguments into other selectors and in this manner drill down to the data you want. Note that if there were two upfront arguments there would also be two variables in the signature of the last setting as well.

Wednesday, April 4, 2018

add a filter in Jira!

Assuming the interface of the moment at Jira on 4/4/2018:

  1. Go to "Issues" by clicking the icon at the far left of the browser which looks like a magnifying glass inspecting four horizontal lines.
  2. Click "View all issues and filters" at the upper right.
  3. Click "New filter" at the upper left.
  4. Change around the controls in a horizontal row below the word "Search" as needed. For example, in typing this up I opened up "Status" and checked the checkboxes for "Open" and "In Progress" to make a filter that will only show these statuses.
  5. Click "Save as" by "Search" to save.
  6. You will be prompted to give a name for your filter. Give a name.
  7. Your filter should appear under the list of "Favorite Filters" at the lower left.

There will be an "Advanced" link at the upper right that when clicked turns into a "Basic" link to toggle back out of "Advanced" and when things are basic the WYSIWYG controls show and when things are advanced you will have the ability to type some query syntax like so:

status in (Open, "In Progress")

Resolve in the Angular 4 paradigm should allow you to hand state on to a component.

Assuming a routing module like so:

import { Routes, RouterModule } from '@angular/router';
import { NgModule } from '@angular/core';
import { WhateverComponent } from './components/whatever.component';
import { WhateverResolverService } from './services/whatever-resolver.service';
export const PlanRoutes: Routes = [
   {
      path: 'yin/:yang',
      component: WhateverComponent,
      resolve: {
         'whateverResolver': WhateverResolverService
      }
   }
];
@NgModule({
   imports: [
      RouterModule.forChild(PlanRoutes)
   ],
   exports: [RouterModule]
})
export class WhateverRoutesModule { }

 
 

One should be able to have a WhateverResolverService to hand a DataContext, fished out of an NgRx store, on to WhateverComponent by crafting something like this:

import { DataContext } from '../../../../whatever/data-models';
import { WhateverAction, getStuff } from '../../../../whatever/store';
import { Observable } from 'rxjs/observable';
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, Resolve, Router, RouterStateSnapshot } from '@angular/router';
import { Store } from '@ngrx/store';
import 'rxjs/add/operator/take';
@Injectable()
export class WhateverResolverService implements Resolve<any> {
   constructor(private router: Router, private store: Store<DataContext>) { }
   
   resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
         Observable<any> {
      const yang = route.params["yang"];
      this.store.dispatch(new WhateverAction(yang));
      return this.store.select(getStuff).take(1);
   }
}

 
 

You will notice that we make use of the yang parameter to go fishing for our data. I was surprised to see that this not like the typical routing snapshot which represents how the route first was and will not reflect updates. Instead, every time the route changes, the resolver will run once. Nice! At the constructor of WhateverComponent we could have something like private store: Store<DataContext> to catch what the resolver hands in. This is an example of a long lingering Observable too. The only one I have every used myself. For all of talk of how one could use an Observable to listen at a web socket and be constantly updated, for the most part I have just interacted with API endpoints and have only done things with Observables that could be done with promises. This is the next level stuff. Forgive the use of "next level" as I know that's all-too-modern slang. WhateverResolverService needs to be looped in at providers at the applicable module.

 
 

Addendum 4/5/2018: What I say above out catching a DataContext at the constructor of the component is wrong. Sorry, I am dealing with an NgRx store at work. Instead you could have a component constructor as follows and do note the reuse of "whateverResolver" too.

constructor(private activatedRoute: ActivatedRoute) {
   this.activatedRoute.data.subscribe(theCaught => {
      console.log('look at this:');
      console.log(theCaught.whateverResolver);
   });
}

 
 

If this were the end of the resolver...

      const simpleObservable = new Observable((observer) => {
         observer.next({ 'foo': 'bar', 'baz': 'qux' });
         observer.complete();
      });
      return simpleObservable;
   }
}

 
 

...then we would be able to log to the console the foo/bar/baz/qux object alright in this approach.