Skip to main content

Note Angular 6+ (p2)

isUndefinedOrNull()

angular.isUndefinedOrNull = function(val) {
    return angular.isUndefined(val) || val === null
}

https://blog.angularindepth.com/everything-you-need-to-know-about-the-expressionchangedafterithasbeencheckederror-error-e3fd9ce7dbb4

https://stackoverflow.com/questions/16017699/how-can-i-check-which-version-of-angular-im-using

https://github.com/eduardoboucas/include-media

https://github.com/eduardoboucas/include-media
https://angular.io/guide/reactive-forms


https://stackoverflow.com/questions/679915/how-do-i-test-for-an-empty-javascript-object
Ext.Object.isEmpty({}); // true // not RxJS

Common ng6+ err
https://stackoverflow.com/questions/45467881/expressionchangedafterithasbeencheckederror-expression-has-changed-after-it-was

https://stackoverflow.com/questions/44614108/when-does-angular-trigger-ngaftercontentchecked

many hook here :) remember WP hookr ?


FormControlName vs NgModel
https://stackoverflow.com/questions/43669773/angular-2-formgroup-expects-a-formgroup-instance-please-pass-one-in
https://blog.angular-university.io/introduction-to-angular-2-forms-template-driven-vs-model-driven/

https://stackoverflow.com/questions/36222845/how-to-get-domain-name-for-service-in-angular2
https://codebeautify.org/base64-to-image-converter
How to configure email signature base64 image ? Webmail Gmail seem not work (show image).
----------------------------------------------------
Copy to Clipboard:

  /* TODO implement for IE, Safari seem not allow copy function (event on Desktop) */
  copiedToClipboard = (containerId) => {

    // if (document.selection) { // IE
    //   var range = document.body.createTextRange();
    //   range.moveToElementText(document.getElementById(containerId));
    //   range.select();
    // } else if (window.getSelection) {
    //   var range = document.createRange();
    //   range.selectNode(document.getElementById(containerId));
    //   window.getSelection().removeAllRanges();
    //   window.getSelection().addRange(range);
    // }
    this.windowFrame.focus();
    this.docFrame.execCommand('selectAll', true);
    // this.docFrame.select();
    var ok = this.docFrame.execCommand('copy');
    if (ok) {
      this.setState({copied: true});
    } else {
      this.setState({copied: false});
    }
  }

DOM to blob
https://embed.plnkr.co/plunk/qWTYma
Seem not what we need but still cool.

Safari:
https://github.com/angular/angular.js/issues/16152

ngclipboard
https://sachinchoolur.github.io/ngclipboard/

Underlying images (css background-image url)  => can not copy, so we have to work around with html2canvas or phantomJS for capture.
https://stackoverflow.com/questions/34635502/convert-angular-view-into-image-for-clipboard

Finally hurrah:
      const range = document.createRange();
      range.selectNode(document.getElementById('sig-preview'));
      window.getSelection().removeAllRanges();
      window.getSelection().addRange(range);
      const copied = document.execCommand('copy');

https://www.w3schools.com/jsref/met_document_execcommand.asp

Original JS here
https://stackoverflow.com/questions/3169786/clear-text-selection-with-javascript
if (window.getSelection) {
  if (window.getSelection().empty) {  // Chrome
    window.getSelection().empty();
  } else if (window.getSelection().removeAllRanges) {  // Firefox
    window.getSelection().removeAllRanges();
  }
} else if (document.selection) {  // IE?
  document.selection.empty();
}

-----------------------------------------------------
Most asked question ab Angular on SO:
https://medium.freecodecamp.org/48-answers-on-stack-overflow-to-the-most-popular-angular-questions-52f9eb430ab0

Dive to observable, async, NESTED case.
https://stackoverflow.com/questions/49596641/is-it-a-good-practice-using-observable-with-async-await
https://medium.com/@luukgruijs/understanding-creating-and-subscribing-to-observables-in-angular-426dbf0b04a3
As some old project, I often have to nested async or something like this to make sure that the API call, task is done. This way seem not good practice since it remove advantage of synchronous or concurrent... So figure out best practice way to handle this. In new Angular there are Observable, Promise ... as long with ES6, React ...

https://stackoverflow.com/questions/37927657/unsafe-value-used-in-a-resource-url-context-with-angular-2/38079724

-----------------------------------------------------
Custom form validation (Reactive Form)
https://codecraft.tv/courses/angular/advanced-topics/basic-custom-validators/
Two-way binding not update status:
https://github.com/angular/angular/issues/18582

Long article and series but worth read. Validation message array in controller seem complex but necessary especially in multi-language app.
https://auth0.com/blog/real-world-angular-series-part-6/

https://stackoverflow.com/questions/15732184/angular-js-validate-form-fields-before-submit
It's very common that many time you got your answer in an article seem not related to the question one. Above is an example. I want to validate multistep form in Angular and have try to find out fast way to do this (I mean copy paste :)), but end up in nothing and have to turn back to RTFM.

Some deep and more detail ab event, validation message status
https://github.com/angular/material/issues/1633

formControlName status check not work:
Not sure why it didn't work with the formControlName approach.

This seems to work though:

<input [formControl]="myForm.controls[fgn].controls['name']">
UPDATE:

You could use this workaround for AOT:

<input [formControl]="myForm.get(fgn + '.name')" />

It seems a bug ?
https://github.com/angular/angular/issues/15206
Many time there are bug in lib, package, especially with less-known and not active maintenance project. Keep and eye to issues list for work around and save time.

Very nature of validation use case. We learned from this that some time we have to think as a user and feel confidence with decision we made.
Damn useful .gif
https://medium.com/frontend-coach/when-and-how-to-validate-form-in-angularjs-95e83d6ad41c

https://stackoverflow.com/questions/31159006/form-validation-on-ng-click-angularjs

It seems submitted not available, may be form DOM or multi form caused this.
http://jasonwatmore.com/post/2018/05/10/angular-6-reactive-forms-validation-example

<!-- TODO required field should have (*) mark -->

(*) [required] vs (optional) ...
I think depend on each case, for example New Relic signup form seem all required so do not have * or optional sign mark for simple.
In case almost required => add (optional) only for field that optional, default treat as required.
In other case, most is optional => only mark * on required seem most useful.

------------------------------------------------
https://stackoverflow.com/questions/51174859/angular-6-service-with-interface
https://blog.hackages.io/angular-single-file-component-4a9eed8c80d5
https://codeburst.io/angular-bad-practices-eab0e594ce92
Components is not match to a page, it should be a part of a page. many components in a page.
Data manipulation => put to model.
Using pipes the right way. Case example unit conversion two dropdown input.

http://reactivex.io/

https://medium.com/front-end-weekly/a-guide-to-debugging-angular-applications-5a36bd88b4cf


-----------------------------------
Beautiful and elegant post ab undefined check
https://dmitripavlutin.com/7-tips-to-handle-undefined-in-javascript/
https://stackoverflow.com/questions/23808928/javascript-elegant-way-to-check-nested-object-properties-for-null-undefined

You can use an utility function like this:

get = function(obj, key) {
    return key.split(".").reduce(function(o, x) {
        return (typeof o == "undefined" || o === null) ? o : o[x];
    }, obj);
}
Usage:

 get(user, 'loc.lat')     // 50
 get(user, 'loc.foo.bar') // undefined
Or, to check only if a property exists, without getting its value:

has = function(obj, key) {
    return key.split(".").every(function(x) {
        if(typeof obj != "object" || obj === null || ! x in obj)
            return false;
        obj = obj[x];
        return true;
    });
}

if(has(user, 'loc.lat')) ...


ngx-select-dropdown
Lib for dropdown

Event
  // TODO try find and use ngx-select-dropdown value attribute or option not programmatic way
  exerciseChanged(event) {
    console.log(event);
    // if (!this.exercise_id) {
    //   const selectedExercise = (event.value) ? ( (event.value[0].id) ? event.value[0].id : '' ) : '';
    //   this.exercise_id = selectedExercise;
    //   this.formIncident.exercise_id = this.exercise_id;
    // }
  }

usage
                <div class="col-sm-6">
                    <div class="form-group injury-exercises">
                        <label for="">Exercises</label>
                        <!-- <select name="exercise_id" formControlName="exercise_id"  id="" class="form-control select-range">
                            <option value="">Select</option>
                            <option *ngFor="let exercise of exercises" value="{{exercise.id}}">{{exercise.name}}</option>
                          </select> -->
                          <!-- <ng-select formControlName="exercise_id" name="exercise_id" class="form-control select-range">
                                <ng-option value="">Select</ng-option>
                                <ng-option *ngFor="let exercise of exercises" [value]="exercise.id" >{{exercise.name}}</ng-option>
                            </ng-select> -->
                        <ngx-select-dropdown [config]="exerciseDropdownConfig" [options]="exercises"
                            [(value)]="exercise_id" (change)="exerciseChanged($event)"></ngx-select-dropdown>
                        <span *ngIf="incidentSubmitted && !formIncident.get('exercise_id').valid" class="text-danger">Excercises is required</span>
                    </div>
                </div>

Controller (component)

export class InjuryLogComponent implements OnInit {
  exerciseDropdownConfig: Object; // List exercises dropdown config key/value/name
...
  ngOnInit() {
    this.exerciseDropdownConfig = {
      search: true, // enables the search plugin to search in the list
      displayKey : 'name',
      limitTo: 5
    }
...
this.injuryS.getExercise().subscribe((data: any) => {
  this.exercises = data.exercises;});


Hurah, as I guested that it require some custom component or event onchange of select dropdown to make formControlName reactive work
It seems work here:
https://github.com/manishjanky/ngx-select-dropdown/issues/15
form

<form [formGroup]="formDemo">
   <ngx-select-dropdwon [options]="['1990','1991','1992','1993']" [(value)]="year" (change)="changeDropDownValue($event)"></sbe-select>
    <input type="hidden" formControlName="year" name="year">
</form>

.ts file
changeDropDownValue($event){
   this.formDemo.patchValue({year: $event})
}


Radix (octa, hexa decimal...)
https://stackoverflow.com/questions/7818903/jslint-says-missing-radix-parameter-what-should-i-do

Long article ab CRUD
https://www.codeproject.com/Articles/1248738/%2FArticles%2F1248738%2FAngular-Data-CRUD-with-Advanced-Practices-of-React

----------------------------------
Technical Debt
https://www.dev6.com/Angular2-Conditional-Validation-with-Reactive-Forms
Conditional required:


A good post ab AngularJS (old) to new Angular (TS)...
Remembering $scope on Ionic Metronic NG1 ?
https://www.simplilearn.com/angularjs-vs-angular-2-vs-angular-4-differences-article

Comments

Popular posts from this blog

AWS Elasticache Memcached connection

https://docs.aws.amazon.com/AmazonElastiCache/latest/mem-ug/accessing-elasticache.html#access-from-outside-aws http://hourlyapps.blogspot.com/2010/06/examples-of-memcached-commands.html Access memcached https://docs.aws.amazon.com/AmazonElastiCache/latest/mem-ug/GettingStarted.AuthorizeAccess.html Zip include hidden file https://stackoverflow.com/questions/12493206/zip-including-hidden-files phpmemcachedadmin ~ phpMyAdmin or phpPgAdmin ... telnet mycachecluster.eaogs8.0001.usw2.cache.amazonaws.com 11211 stats items stats cachedump 27 100 https://docs.aws.amazon.com/AmazonElastiCache/latest/mem-ug/VPCs.EC.html https://lzone.de/cheat-sheet/memcached VPC ID Security Group ID (sg-...) Cluster: The identifier for the cluster memcached1 Creation Time: The time (UTC) when the cluster was created January 9, 2019 at 11:47:16 AM UTC+7 Configuration Endpoint: The configuration endpoint of the cluster memcached1.ahgofe.cfg.usw1.cache.amazonaws.com:11211 St...

Notes Windows 10 Virtualbox config, PHP Storm Japanese, custom PHP, Apache build, Postgresql

 cmd => Ctrl + Shift + Enter mklink "C:\Users\HauNT\Videos\host3" "C:\Windows\System32\drivers\etc\hosts" https://www.quora.com/How-to-create-a-router-in-php https://serverfault.com/questions/225155/virtualbox-how-to-set-up-networking-so-both-host-and-guest-can-access-internet 1 NAT + 1 host only config https://unix.stackexchange.com/questions/115464/how-to-properly-set-up-2-network-interfaces-in-centos-running-in-virtualbox DEVICE=eth0 TYPE=Ethernet #BOOTPROTO=dhcp BOOTPROTO=none #IPADDR=10.9.11.246 #PREFIX=24 #GATEWAY=10.9.11.1 #IPV4_FAILURE_FATAL=yes #HWADDR=08:00:27:CC:AC:AC ONBOOT=yes NAME="System eth0" [root@localhost www]# cat /etc/sysconfig/network-scripts/ifcfg-eth1 # Advanced Micro Devices, Inc. [AMD] 79c970 [PCnet32 LANCE] DEVICE=eth1 IPADDR=192.168.56.28 <= no eff => auto like DHCP #GATEWAY=192.168.56.1 #BOOTPROTO=dhcp BOOTPROTO=static <= no eff ONBOOT=yes HWADDR=08:00:27:b4:20:10 [root@localhost www]# ...

Rocket.Chat DB schema

_raix_push_notifications avatars.chunks avatars.files instances meteor_accounts_loginServiceConfiguration meteor_oauth_pendingCredentials meteor_oauth_pendingRequestTokens migrations rocketchat__trash rocketchat_cron_history rocketchat_custom_emoji rocketchat_custom_sounds rocketchat_import rocketchat_integration_history rocketchat_integrations rocketchat_livechat_custom_field rocketchat_livechat_department rocketchat_livechat_department_agents rocketchat_livechat_external_message rocketchat_livechat_inquiry rocketchat_livechat_office_hour rocketchat_livechat_page_visited rocketchat_livechat_trigger rocketchat_message rocketchat_oauth_apps rocketchat_oembed_cache rocketchat_permissions rocketchat_raw_imports rocketchat_reports rocketchat_roles rocketchat_room rocketchat_settings rocketchat_smarsh_history rocketchat_statistics rocketchat_subscription rocketchat_uploads system.indexes users usersSessions https://rocket.chat/docs/developer-guides/sc...