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

Categories
Uncategorized

Empty json_encode() output in php 7.1.x

If you have an empty json_encode() and don’t know what the hell just went wrong, then this piece of code is really helpful.

$json = json_encode(array('message' => 'OK', 'data' => $row["description"]));
if ($json) {
    echo $json;
} else {
    error_log(json_last_error_msg());
}

If you get an error saying invalid UTF-8 characters or something similar, then all you need to do is set the character set of your database to UTF-8 in the following way.

connect_errno) {
    echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
    die();
}

 var_dump($mysqli->get_charset());
// you should see something like 'latin1'

 if (!$mysqli->set_charset("utf8")) {
    error_log("Error loading character set utf8: %s\n", $mysqli->error);
    exit();
}

var_dump($mysqli->get_charset());
// you should see something like 'UTF-8'

// Do your stuff here.

$mysqli->close();
Categories
Uncategorized

Check if input is a number in PHP 7.1.x

is_int()

The is_int() doesn’t tell you if the string is actually a number, instead it returns false.

If you convert your string numeric into an int and then do this, only then will it work. But there is a problem with this approach, while converting string to an int, we use intval(). This converts strings to 0's.

is_numeric()

So the best way to find out whether a variable is an actual numeric or not is to use this php function.

Categories
Uncategorized

Delete Cookies in JavaScript

Deleting a cookie stored in a browser using JavaScript is very easy. For example if you have a cookie named token in your browser and want to delete it, all you have to do is provide the cookie name and set it to a past date. This deletes it immediately. You can take a look at cookies in chrome’s developer tools.
Cookies

function setCookie(name, value, days) {
  var d = new Date();
  d.setTime(d.getTime() + (days * 24 * 60 * 60 * 1000));
  var expires = 'expires=' + d.toUTCString();
  document.cookie = name + '=' + value + ';' + expires + ';path=/';
}

function deleteCookie(name) {
  document.cookie = name + '=;expires=' + new Date(1970, 0, 1).toUTCString() + ';path=/'
}

setCookie('token', 'value here', 1);

deleteCookie('token');

Demo

Categories
Uncategorized

Add HTTP Intercepter in Angular 4

Creating a HTTP Intercepter

Angular V4.4.4
We need to inherit the ‘HttpIntercepter’ class and override the ‘intercept’ method to be able to intercept all the HTTP requests you make using ‘HttpClient’.
auth-interceptor.ts

import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
// import 'rxjs/add/operator/do';
import {HttpEvent, HttpResponse, HttpInterceptor, HttpHandler, HttpRequest} from '@angular/common/http';
 
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
  constructor(private auth: AuthService) {}
 
  intercept(req: HttpRequest, next: HttpHandler): Observable> {
    // Clone the request as it is immutable. You can also save the original request in the following way
    // const prevReq = req.clone();
    const authReq = req.clone({headers: req.headers.set('Authorization', 'Bearer ' + getToken())});
    // or you can use the shorter version of the same.
    //const authReq = req.clone({setHeaders: {Authorization: 'Bearer ' + getToken()}});
    // Pass on the cloned request instead of the original request.
    return next.handle(authReq);
    /* you can test the above function by doing a console.log() here. For this you will need to import 'HttpResponse' and the 'do' operator.
     .do(event => {
        if (event instanceof HttpResponse) {    
          console.log(getToken());
        }
      });
   */
  }
}

Updating app.module.ts

Now you need to include the ‘AuthInterceptor’ class as part of our main app module providers after you have imported ‘HTTP_INTERCEPTORS’.
app.module.ts

import {NgModule} from '@angular/core';
import {AuthInterceptor} from './auth-interceptor'
import {HTTP_INTERCEPTORS} from '@angular/common/http';

@NgModule({
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: AuthInterceptor,
    multi: true,
  }],
})
export class AppModule {}
Categories
Uncategorized

Simple Javascript function to convert to timeAgo.js

Calculate the time difference for javascript date objects in years, months, days, hours, minutes and seconds. Whether they are in the future or in the past. The function accounts for all very easily. Since this is a lightweight function you can easily use this as part of any application, without incurring much overhead.

Code

var timeAgo = function(date) {
  var d = new Date();
  var UTCsecondsNow = (d.getTime() + d.getTimezoneOffset() * 60 * 1000);
  var UTCseconds = (date.getTime() + date.getTimezoneOffset() * 60 * 1000);
  var diff = UTCsecondsNow - UTCseconds;
  var tense = 'ago';
  if (diff < 0) {
    tense = 'later';
    diff = Math.abs(diff);
  }
  if (diff === 0) return 0;
  // 365.25 * 24 * 60 * 60 * 1000
  var years = singular(Math.round(diff / 31557600000), 'Year');
  if (years)
    return years + tense;
  var months = singular(Math.round(diff / 2592000000), 'Month');
  if (months)
    return months + tense;
  var days = singular(Math.round(diff / 86400000), 'Day');
  if (days)
    return days + tense;
  var hours = singular(Math.round(diff / 3600000), 'Hour');
  if (hours)
    return hours + tense;
  var mins = singular(Math.round(diff / 60000), 'Minute');
  if (mins)
    return mins + tense;
  var secs = singular(Math.round(diff / 1000), 'Second');
  if (secs)
    return secs + tense;
};

var singular = function(num, str) {
  if (num > 1) {
    if (num === 1)
      return '1 ' + str + ' ';
    else
      return num + ' ' + str + 's ';
  }
  return '';
};

Usage

timeAgo( new Date('2016-12-04T11:45:00.000Z') )

Output

10 Months ago

Categories
Uncategorized

Refresh your app automatically in the browser with gulp & livereload

Add livereload to your dev in 5 mins

You will need to install gulp-server-livereload for this. This utilizes web sockets. Make sure you have a compatible version of node+npm before you run this. This will install gulp-server-livereload as a dev dependency in your node modules folder and add it to your package.json file.

npm i gulp-server-livereload --save -D

Add the following code to gulpfile.js and run gulp livereload, it should open up your default browser and load your app at localhost:8000.
Note: Make sure you have an index.html file in your app inside the public folder.

var gulp = require('gulp');
var server = require('gulp-server-livereload');
gulp.task('livereload', function() {
  gulp.src('public')
    .pipe(server({
      livereload: true,
      directoryListing: false,
      open: true
    }));
});
Categories
Uncategorized

Invalid Object & Array Manipulations in Vue.js 2

Objects

  let obj = {name: 'Shiva'
             occupation: 'coder'}
delete obj.name
// or delete obj['name']
obj.name = 'Charan'
// or obj['name'] = 'Charan'

This is how you would usually set delete/add/set properties in Javascript. But Vue.js 2 can’t detect the changes if the object is manipulated in this fashion.
For it to be able to detect these changes, use the following.

Vue.set(obj, 'name', 'Shiva')

or

this.$set(obj, 'name', 'Shiva')

Arrays

Similarly for arrays, if we use the following, then Vue.js 2 fails to detect the changes in state.

let arr = [1,2,3,4]
arr[0] = 9

You will have to use the following commands to be able to deal with the above situation and many others.
Vue.js 2 has wrapped methods to help us create work arounds for such issues.

// Vue.set
this.$set(arr, 0, 9)
// or
arr.splice(0, 1, 9)

Wrapped methods

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()
Categories
Uncategorized

async & await in ES2017/ES8

async

Adding an async keyword to a function makes it asynchronous as the name itself suggests and it also return a promise instead of the value. We can define an ES6 function as async using the following syntax. This works with the old function syntax as well.

let myFunc = async() => {
  return 'Hi I am async!';
};
console.log(myFunc());
// logs Promise {[[PromiseStatus]]: "resolved", [[PromiseValue]]: "Hi I am async!"}

/* Resolving a promise */
myFunc().then((result) => {
  console.log(result);
// logs: Hi I am async!
}).catch((err) => {
  console.log(err);
});

await

The await keyword can only be used inside an async function. When used, while calling an async function, it resolves the promise and returns the value.
The above code can be made more readable, by using the await keyword.

let myFunc = async() => {
  return 'Hi I am async!';
};
let finalSync = async() => {
  console.log(await firstAsyncFunc());
// logs: Hi I am async
};
finalSync();

Here is a live example of asynchronous functions in action. Although the first function is called first, we don’t have to wait until the promise is resolved to a result by await, instead we can see rest of the functions calls and their promises being resolved earlier.
Code

let firstAsyncFunc = async() => {
  setTimeout(function() {
    console.log('First');
  }, 3000);
};
let secondAsyncFunc = async() => {
  console.log('Second');
};
let thirdAsyncFunc = async() => {
  return 'Third';
};
let finalSync = async() => {
  await firstAsyncFunc();
  await secondAsyncFunc();
  console.log(await thirdAsyncFunc());
};
finalSync();

Output

Second
Third
First

Demo

Sequential calls vs Parallel calls

The following is an example of sequential asynchronous function calls

let finalSync = async() => {
  await firstAsyncFunc();
  await secondAsyncFunc();
};
finalSync();

If you want to make asynchronous function calls simultaneously, then you could use Promise.all and supply it with an array of asynchronous functions and then use await to return the result after all the calls are made.

let finalSync = async () => {
  await Promise.all([async1(), async2()]);
}
finalSync();