Categories
Uncategorized

SimpleJS lightweight javascript library

SimpleJS is a lightweight javascript library to get you started on plane javascript project that doesn’t need libraries to start with.
Some of the major functionality includes the following.

  • Manipulate Cookies.
  • Make GET, POST calls with JSON data.
  • Load attributes to an element by passing an object.
  • Insert element before an element in DOM.
  • Get Parent element in DOM.
Categories
Uncategorized

Calculate time ago string in Angular 5

github

import {timeAgo} from './time-ago.ts';
...
// Pass Date Object and it returns a string.
timeAgo(new Date());

You need to pass a date object and this method returns a string. This is compatible with Angular 5.0.3.

Categories
Uncategorized

Using bootstrap 4 modal with Angular 5

Make sure you have jquery and bootstrap installed.
or else you can use the following commands.

npm i jquery bootstrap@4.0.0-beta.2 --save

If you are using angular-cli, then you need to include the jquery in the scripts section of .angular-cli.json file. The same goes with bootstrap files as well. My file looks somewhat similar to the following.

"styles": [
        "../node_modules/bootstrap/dist/css/bootstrap.min.css",
        "../node_modules/font-awesome/css/font-awesome.min.css",
        "styles.scss"
      ],
      "scripts": [
        "../node_modules/jquery/dist/jquery.slim.min.js",
        "../node_modules/popper.js/dist/umd/popper.min.js",
        "../node_modules/bootstrap/dist/js/bootstrap.min.js"
      ],

Here is the HTML you would want to use to trigger the modal to show up. The fade class is removed from the modal with id = “exampleModal” when the button with the attributes data-toggle = “modal” data-target = “#exampleModal” is clicked.

HTML






Programmatically

If you want trigger the opening and closing of the modal programmatically, then use the following in your methods inside the component with the above HTML after installing the required.

npm install @types/jquery --save

This is the best approach if all that we want to use is the modal. We can avoid the overhead of an angular wrapper around bootstrap jQuery functions.
Now in the component in which you are using jQuery import it as the following.

import * as $ from 'jquery';
// opening
$('#modalTrigger').click();

// closing
 $('#postJobModalClose').click();
Categories
Uncategorized

Using multiple guards for a route in Angular

The canActivate( ) method which should be overridden, should return only one of the following types

  • Observable<boolean>
  • Promise<boolean>
  • boolean

The multiple routes work like an ‘&&’ condition in javascript, i.e., angular won’t execute the later guards, if the first one fails.

app-routing.module

import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';

import {HomeComponent} from './home.component';
import {GuardOne} from './guard-one.guard';
import {GuardTwo} from './guard-two.guard';

const routes: Routes = [
    {
        path: '',
        redirectTo: '/home',
        pathMatch: 'full'
    },
    {
        path: 'home',
        canActivate: [GuardOne, GuardTwo],
        component: HomeComponent,
    }
];

@NgModule({
    imports: [RouterModule.forRoot(routes)],
    exports: [RouterModule]
})
export class AppRoutingModule {
}

guard-one.guard

import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';

import {LoginService} from './user.service';

@Injectable()
export class GuardOne implements CanActivate {

    constructor(private router: Router, private userLoginSer: LoginService) {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        if (!this.userLoginSer.user) {
         // you can send them to some other route like this.
         // this.router.navigate(['/nonUserHome']);
            return false;
        } else {
            return true;
        }
    }
}

guard-two.guard

import {Injectable} from '@angular/core';
import {Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot} from '@angular/router';

import {LoginService} from './user.service';

@Injectable()
export class GuardTwo implements CanActivate {

    constructor(private router: Router, private userLoginSer: LoginService) {
    }

    canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
        if (!this.userLoginSer.login) {
         // you can send them to some other route like this.
         // this.router.navigate(['/login']);
            return false;
        } else {
            return true;
        }
    }
}

The login service that is being used above can be somewhat like this:

guard-two.guard

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Injectable()
export class LoginService {
    login = true;
    user = true;

    constructor(private http: HttpClient) {
    }
}

For these files to work, you need to add them to the app.module.ts and also use in the main component where you would like to use the router.

Categories
Uncategorized

HTTP call in Angular 5

The approach that will be discussed in this post uses the recommended HttpClient from angular 4.

login.service.ts

import {Injectable} from '@angular/core';
import {HttpClient} from '@angular/common/http';
import {Observable} from 'rxjs/Observable';

import {LoginObj} from './login-obj';
// import {ReturnObj} from './return-obj';
import {baseUrl} from '../backend';

@Injectable()
export class LoginService {
    
    constructor(private http: HttpClient) {
    }

    // submitUser(obj: LoginObj): Observable {
    submitUser(obj: LoginObj): Observable {
        return this.http.post(`${baseUrl}login.php`, obj);
    }
}

The above login service returns an observable of type any. We can also validate the object being returned by expecting a certain class.
Now the service needs to be injected into the component that we are going to use.

login.component.ts

import {Component, OnInit} from '@angular/core';
import {Observable} from 'rxjs/Observable';

import {LoginService} from './login.service';
import {LoginObj} from './login-obj';

@Component({
    selector: 'app-login',
    templateUrl: './login.component.html',
    styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {

    loading = false;
    errorMessage = '';
    successMessage = '';
    loginObj = new LoginObj();
   
    constructor(private userLoginSer: LoginService) {}

    ngOnInit(): void {}

    onLoginSubmit(): void { 
            this.loading = true;
            this.userLoginSer.submitUser(this.loginObj)
                .finally(() => {
                    // This does exactly what it says, it executes finally irrespective of success, failure.
                    this.loading = false;
                })
                .subscribe(returnObj => {
                   this.successMessage = 'Hurray!';
                    },
                    error => {
                        this.errorMessage = 'Sorry! Something went wrong!';
                    },
                      () => {  
                       // onComplete
                       // This runs only if it is a success and after the code in the success block.
                        });
        }
    }

The login and return classes may look somewhat like this,

login-obj.ts

export class LoginObj {
    message: string
    constructor() {
    }
}

return-obj.ts

export class ReturnObj {
    message: string
    constructor() {
    }
}

Now we finally need to add the service and component into the app.module.ts.

The service goes into the providers section, and the component goes into the declarations.

app.module.ts

import {NgModule} from '@angular/core';

import {LoginComponent} from './login.component';
import {LoginService} from './login.service';

@NgModule({
    declarations: [
        LoginComponent,
      ...],
     ....
    providers: [
       LoginService,
       ....
     ],
   ...
})

export class AppModule {
}
Categories
Uncategorized

How to make reCaptcha v2/ Invisible API call to verify request with PHP 7.1.x

Make sure that you have listed the domain you are using to run this piece of php code, under the list of allowed domains in your corresponding recaptcha module in google.
Enter
recaptcha.php

 $secret, 'response' => $_POST['recaptcha']);
    // use key 'http' even if you send the request to https://...
    $options = array(
        'http' => array(
            'header' => "Content-type: application/x-www-form-urlencoded\r\n",
            'method' => 'POST',
            'content' => http_build_query($data)
        )
    );
    $context = stream_context_create($options);
    $result = file_get_contents($url, false, $context);
    if ($result === FALSE) {
        error_log('https request to Google API failed!');
        echo '{"message" : "Sorry! Something went wrong."}';
    } else {
        $result = json_decode($result, true);
        if (!$result) {
            error_log(json_last_error_msg());
            echo '{"message" : "Sorry! Something went wrong."}';
        } else {
            if ($result["success"] === true) {
                echo '{"message" : "OK"}';
            } else {
                error_log("error : " . $result["challenge_ts"]
                    . "hostname : " . $result["hostname"]
                    . "error-codes : " . $result["error-codes"]);
                echo '{"message" : "Sorry! Something went wrong."}';
            }
        }
    }
}
Categories
Uncategorized

Using preg_match in php 7

Let us take can example of a function that checks whether a given string is a .edu email address or not.

Categories
Uncategorized

State Management in Angular 5.x using ngrx

state management

job-state.ts

Let us assume we have a job object with the following properties.

export interface JobState {
    id: number;
    title: string;
    company: string;
    city: string;
    state: string;
    zip: number;
}

job-state.ts

Let us create actions classes by implementing the Action interface and then export them with type All, to avoid type mismatch errors.

import {Action} from '@ngrx/store';

import {JobState} from './job-state';

export const ADDJOB = 'ADDJOB';
export const GETJOB = 'GETJOB';

export class AddJobPost implements Action {
    readonly type = ADDJOB;

    constructor(public payload: JobState) {
    }
}

export class GetJobPost implements Action {
    readonly type = GETJOB;
}

export type All = AddJobPost | GetJobPost;

job.reducer.ts

Now we need to create the reducer which maps the actions to the correct state.

import * as PostActions from './job-actions';
import {JobState} from './job-state';

export type Action = PostActions.All;

const emptyJobState = {
    id: null,
    title: null,
    company: null,
    city: null,
    state: null,
    zip: null,
};

const newState = (state, newData) => {
    return Object.assign({}, state, newData);
};

export function jobReducer(state: JobState = emptyJobState, action: Action) {
    switch (action.type) {
        case PostActions.ADDJOB: {
            return newState(state, action.payload);
        }
        case PostActions.GETJOB: {
            return Object.assign({}, state);
        }
        default: {
            return Object.assign({}, state);
        }
    }
}

app.component.ts

Now we need to include the reducer in the component, that we can to make use of this functionality. Here let us consider app.component.ts

import {Component, OnInit} from '@angular/core';
import {Store} from '@ngrx/store';

import * as PostActions from '../reducers/job-actions';
import {JobState} from './job-state';
import {JobStateInterface} from './job-state.interface';

@Component({
    selector: 'app',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
    job: Observable;
    jobs: JobState[];

    constructor(private store: Store) {
        this.job = store.select('job');
    }

 
    setJob(obj: JobState): void {
        this.store.dispatch(new PostActions.AddJobPost(obj));
    }

}

job-state.interface.ts

We need to define the interface that the store uses to retrieve the state.

import {JobState} from './job-state';

export interface JobStateInterface {
    job: JobState;
}

app.module.ts

Finally we need to add the reducer to the app.module.ts. There is a nice chrome plugin called redux dev-tools</ that comes in handy to view the current state of the application and manipulate it. You need add the StoreDevtoolsModule line as shown below, after installing and enabling the above plugin in your code.

// ...
import {job} from 'job.reducer';

@NgModule({
// ...

 imports: [
        BrowserModule,
        AppRoutingModule,
        FormsModule,
        HttpClientModule,
        StoreModule.forRoot({login: loginReducer, job: jobReducer}),
        StoreDevtoolsModule.instrument({
            maxAge: 25
        }),

// ...
})

// ...
Categories
Uncategorized

Parameterized Pipes for input search in Angular (custom filters)

Lets say we want to filter through a list of jobs that look like the following using an Angular 4.4.5 setup.

job-state.ts

export interface JobState {
    id: number;
    title: string;
    company: string;
    city: string;
    state: string;
    zip: number;
}

jobs filter

We need to create a custom pipe that takes in the search term as an input parameter for this.

search-jobs.pipe.ts

import {Pipe, PipeTransform} from '@angular/core';

import {JobState} from './job-state';

@Pipe({
    name: 'searchJobs'
})
export class SearchJobsPipe implements PipeTransform {
    transform(jobs: JobState[], searchText: string): any[] {
        if (!jobs) {
            return [];
        }
        if (!searchText) {
            return jobs;
        }
        searchText = searchText.toLowerCase();
        return jobs.filter(it => {
            return it.title.toLowerCase().includes(searchText) ||
                it.company.toLowerCase().includes(searchText) || it.city.toLowerCase().includes(searchText) ||
                it.state.toLowerCase().includes(searchText) || it.zip.toString().toLowerCase().includes(searchText);
        });
    }
}

app.module.ts

Now add this app.module.ts to the Declarations part of NgModule, after including the AppComponent where you wish to use this.

// ...

import {AppComponent} from './app.component';
import {SearchJobsPipe} from './search-jobs.pipe';

@NgModule({
    //
     ...

     declarations: [ AppComponent,
                    SearchJobsPipe 
                  ],

    // ....
}]

app.component.ts

Make sure you have app.component.ts that is somewhat similar to the base structure here.

import { Component, OnInit } from '@angular/core';
import {JobState} from './job-state';

@Component({
  selector: 'app-app1',
  templateUrl: './app1.component.html',
  styleUrls: ['./app1.component.scss']
})
export class App1Component implements OnInit {
  jobSearch = '';
  jobs: JobState[];

  constructor() { }

  ngOnInit() {
     this.getJobs();
  }

  getJobs(): void {
  // Make API call here and load the jobs on success 
  // this.jobs = response.data;
  }

}

app.component.html

Now add the following code into your app.component.html file or your components template.



{{job.title}} - {{job.company}}
{{job.city}}, {{job.state}} - {{job.zip}}
Categories
Uncategorized

Add font awesome icons to Bootstrap 4 input

inline search icon

Note
Before you run this code, make sure you have jQuery 3.x, Bootstrap 4.x, and Font Awesome 4.x in the same order.

HTML

CSS

body {
  padding: 12px;
}

.search-class {
  border: none;
  background: #ffffff;
}

.icon-search {
  border: 1px solid #f2f2f2;
  border-top-left-radius: .25em;
  border-bottom-left-radius: .25em;
  border-right: none;
  padding-right: 0;
}

.input-search {
  border: 1px solid #f2f2f2;
  border-top-right-radius: .25em;
  border-bottom-right-radius: .25em;
  border-left: none;
}

.input-search:focus {
  border-color: #f2f2f2;
}

.search-class-width {
  max-width: 400px;
}

Demo