• This is Slide 1 Title

    This is slide 1 description. Go to Edit HTML and replace these sentences with your own words. This is a Blogger template by Lasantha - PremiumBloggerTemplates.com...

  • This is Slide 2 Title

    This is slide 2 description. Go to Edit HTML and replace these sentences with your own words. This is a Blogger template by Lasantha - PremiumBloggerTemplates.com...

  • This is Slide 3 Title

    This is slide 3 description. Go to Edit HTML and replace these sentences with your own words. This is a Blogger template by Lasantha - PremiumBloggerTemplates.com...

Thứ Năm, 15 tháng 10, 2020

Restorem database vào một database khác

 Mục dịch là save một Database cũ vào một Database mới , với tên khác, tên log và mdf khác luôn.

1. Backup database muốn restore

2. Vào Restore database với 

  - Option: Overwrite the existing database (WITH REPLACE)

  - Files: Chỗ Restore As chọn tới file mdf và .ldf mới mà bạn muốn thay thế.



Error when build IOS ionic - Upload IOS to Appstore by xcrun


I. Upload IOS to App Store by xcrun
1. Generate .ipa file with signed. 
    Product -> archive

2. move to ipa folder

3. check ipa file

xcrun altool --validate-app --file "$IPA_PATH" --username "$APP_STORE_USERNAME" --password "sjjkh-asjdkh-asjkdh"


password: get from appleid.apple.com/account/manage

APP-SPECIFIC PASSWORD (one time pass)

4. Upload file
xcrun altool --upload-app --file "$IPA_PATH" --username "$APP_STORE_USERNAME" --password "sjjkh-asjdkh-asjkdh" --verbose

ex: xcrun altool --upload-app --file "Citypost2020.ipa" --username "techhub@citypost.com.vn" --password "isub-wxzt-aqvs-apav" --verbose


II. Error when build IOS ionic
1. Install cordova-res when you get error
sudo npm i -g cordova-res --unsafe-perm

2. Error when run emulate or device

sudo npm install @ionic/app-script@latest --save-dev 

3. Error node-sass

npm rebuild node-sass 

4. Error when take picture "Thread 5: signal SAGABRT" and location: Edit info plist

go to TARGET -> Info -> add (+) key -value

Privacy - Camera Usage Description : Chụp ảnh báo phát

Privacy - Location Always Usage Description : Định vị báo phát

Privacy - Location When In Use Usage Description Định vị báo phát

Info Plist

4. Error when take picture "Thread 5: signal SAGABRT" and location: Edit info plist






Thứ Tư, 14 tháng 10, 2020

No version of NDK matched the requested version

Lỗi NDK : No version of NDK matched the requested version 21.0.6113669. Versions available locally: 21.3.6528147

Cập nhật lại NDK version cho đúng:
Trên adnroid studio: -> Tool -> SDK Manager -> Chuyển qua tab SDK tooks -> check vào NDK (Side by side) để update lên bản mới nhất.

Nếu vẫn không được vào đây tải bản phù hợp: https://androidsdkoffline.blogspot.com/p/android-ndk.html

sau đỏ bỏ vào: C:\Users\"Username"\AppData\Local\Android\Sdk\ndk\

Thứ Ba, 29 tháng 9, 2020

Validator Form In Angular

Have 2 ways validate form in angular.

First Way: Use FormBuilder

HTML file

 <form [formGroup]="angForm" novalidate>

<div class="form-group"> <label class="center-block">Name: <input class="form-control" formControlName="name"> </label> </div> <div *ngIf="angForm.controls['name'].invalid && (angForm.controls['name'].dirty || angForm.controls['name'].touched)" class="alert alert-danger"> <div *ngIf="angForm.controls['name'].errors.required"> Name is required. </div> </div> </form> <p>Form value: {{ angForm.value | json }}</p> <p>Form status: {{ angForm.status | json }}</p>

TS file

import { FormGroup, FormBuilder, Validators } from '@angular/forms';
@Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { title = 'Angular Form Validation Tutorial'; angForm: FormGroup; constructor(private fb: FormBuilder) { this.createForm(); } createForm() { this.angForm = this.fb.group({ name: ['', Validators.required ] }); } }

Second Way: Use ngModel
Create model file class
    
export class ContactForm {
    constructor(
        public namestring,
        public emailstring,
        public subjectstring,
        public phone?: string,
        public content?: string
    ) { }
}

HTML File
<form (ngSubmit)="onSubmit()" #requestForm="ngForm" id="requestForm" name="requestForm">
    <div class="row">
        <div class="col-lg-6">
            <input class="form-control" type="text" name="name" value="" size="40" required minlength="2" appForbiddenName="admin"
            [(ngModel)]="model.name" #name="ngModel" #_name placeholder="(1) Họ tên *">
            
        </div>
        <div class="col-lg-6">
            <input class="form-control" type="email" name="email" #_email value="" size="40"
                aria-required="true" aria-invalid="false" placeholder="Email">
        </div>
        <div class="col-lg-6">
            <input class="form-control" type="text" name="subject" value="" size="40" required minlength="3" #_subject
                #subject="ngModel" [(ngModel)]="model.subject" aria-invalid="false" placeholder="(2) Tiêu đề *">
        </div>

        <div class="col-lg-6">
            <input class="form-control" type="text" name="phone" value="" size="40" required pattern="^\+?(?:[0-9]??).{5,14}[0-9]$" #_phone
                #phone="ngModel" [(ngModel)]="model.phone" aria-required="true" aria-invalid="false" placeholder="(3) Số điện thoại *">
        </div>
        <div class="col-xs-12">
            <textarea class="form-control" name="message" cols="40" rows="4" required #_message
            #message="ngModel" [(ngModel)]="model.content" aria-invalid="false" placeholder="(4) Nội dung bạn quan tâm *"></textarea>
        </div>
        <div class="col-xs-12">
            <input class="btn btn-primary" [disabled]="!requestForm.form.valid" type="submit" #submit_bt value="    Gửi    ">
        </div>
    </div>
</form>
<div>
    <p *ngIf="name.invalid && (name.dirty || name.touched)" class="alert alert-danger">
        <span *ngIf="name.errors.required">
            (1) Họ tên không được trống.
        </span>
        <span *ngIf="name.errors.minlength">
            (1) Tên ít nhất phải 2 ký tự.
        </span>
        <span *ngIf="name.errors.forbiddenName">
            (1) Tên bạn không thể là "admin".
        </span>
    </p>
    <p *ngIf="subject.invalid && (subject.dirty || subject.touched)" class="alert alert-danger">
        <span *ngIf="subject.errors.required">
            (2) Tiêu đề không được trống.
        </span>
        <span *ngIf="subject.errors.minlength">
            (2) Tiêu đề ít nhất phải 3 ký tự.
        </span>
    </p>
    <p *ngIf="phone.invalid && (phone.dirty || phone.touched)" class="alert alert-danger">
        <span *ngIf="phone.errors.required">
            (3) Số điện thoại không được trống.
        </span>
        <span *ngIf="phone.errors.pattern">
            (3) Điện thoại không đúng định dạng.
        </span>
    </p>
    <p *ngIf="message.invalid && (message.dirty || message.touched)" class="alert alert-danger">
        <span *ngIf="message.errors.required">
            (4) Nội dung không được trống.
        </span>
    </p>
</div>

TS File

import { Contact } from '../../Class/contact';
model = new Contact('','','','','');
  @ViewChild('_name', {static: true}) name: ElementRef;
  @ViewChild('_subject', {static: true}) subject: ElementRef;
  @ViewChild('_phone', {static: true}) phone: ElementRef;
  @ViewChild('_email', {static: true}) email:ElementRef;
  @ViewChild('_message', {static: true}) message: ElementRef;
  // @ViewChild('submit_bt',{static: true}) submit_bt: ElementRef;
  async onSubmit(){
    let _name = this.name.nativeElement.value;
    let _subject = this.subject.nativeElement.value;
    let _phone = this.phone.nativeElement.value;
    let _email = this.email.nativeElement.value;
    let _message = this.message.nativeElement.value;
    alert(_name + " - " + _subject + " - " + _phone + " - " + _email + " - " + _message)
  }

Không cần khai báo trong ts file, nhưng muốn lấy giá trị form cần dùng @ViewChild('Name',{static:true}) name:ElementRef;

Thứ Năm, 16 tháng 7, 2020

Upload file in node js / Upload file bẳng nodejs

Các bước để tạo một API server bằng node js thì mình không làm nữa, chỉ bắt đầu bằng việc up ảnh

Bước 1: Tạo service upload ảnh

const multer = require('multer'// import library
const moment = require('moment')
const q = require('q')
const _ = require('underscore')
var file = require('file-system');
const fs = require('fs')
const dir = './public'
let sub = moment(moment.now()).format('YYYY-MM');
/** Store file on local folder */
let storage = multer.diskStorage({
    destination: function (reqfilecb) {
        cb(null'public/' + sub)
    },
    filename: function (reqfilecb) {
        let date = moment(moment.now()).format('YYYYMMDDHHMMSS')
        cb(nulldate + '_' + file.originalname.replace(/-/g'_').replace(/ /g'_'))
    }
})

/** Upload files  */
let upload = multer({ storage: storage }).array('files')

/** Exports fileUpload function */
module.exports = {
    fileUpload: function (reqres) {
        let deferred = q.defer()
        /** Create dir if not exist */
        if (!fs.existsSync(dir + "/" +sub)) {
            fs.mkdirSync(dir + "/" + sub)
            console.log(`\n\n ${dir} dose not exist, hence created \n\n`)
            
        }

        upload(reqresfunction (err) {
            if (req && (_.isEmpty(req.files))) {
                deferred.resolve({ status: 200message: 'File not attached'data: [] })
            } else {
                if (err) {
                    deferred.reject({ status: 400message: 'error'data: err })
                } else {
                    deferred.resolve({
                        status: 200,
                        message: 'File attached',
                        filename: _.pluck(req.files,
                            'filename'),
                        data: req.files
                    })
                }
            }
        })
        return deferred.promise
    }
}

Bước 2: Tạo route API về controller : fileUploadController.js

var fileUploadService = require('../services/fileUploadService');

function fileUploadController() {

    // var fileUploadService = _fileUploadService();
    
    async function uploadFile(reqres) {
        fileUploadService.fileUpload(reqres)
            .then(fileUploadServiceResponse => {
                res.status(200).send(fileUploadServiceResponse)
            })
            .catch(error => {
                res.status(400).send(error)
            })
    }

    // async function uploadFile(req, res, next) {
    //     console.log(req);
    //     if(req.file == null){
    //         return res.send("Không Có hình")
    //     } else {
    //         return res.send("Có hình")
    //     }
    // }

    return {
        uploadFile: uploadFile
    }
}

module.exports = fileUploadController;

Bước 3: Check lại với postman




Load css another page when you got a conflict / Load css cho admin

loadStyle() {
    this.document.getElementsByTagName('head')[0].innerHTML+='<link rel="stylesheet" 
href="../assets/admin/dist/css/adminlte.min.css">';
  }

ngOnInit() {
    // if (localStorage.getItem('unserInfo') == null){
    //   this.router.navigate(['login']);
    // }
    this.loadStyle();
  }

Thứ Ba, 4 tháng 2, 2020

Một số command line cần thiết khi sử dụng Angular CLI

- ng 
   - g : Tự động tạo
   - c : component
   - m : module
   - s : service
Các option
--save : lưu vào package.json
--flat : Không tạo thư mục
--spec false: không tạo file spect.ts
-it : Không tạo file html
-is: Không tạo file css

Các Lỗi khi build API Node JS

1. Lỗi không thể connect đến MSSQLSERVER:
onnectionError: Failed to connect to localhost\MSSQLSERVER in 15000ms
    at ConnectionError (D:\APINode\node_modules\tedious\lib\errors.js:13:12)
    at Connection.connectTimeout (D:\APINode\node_modules\tedious\lib\connection.js:1190:54)
    at Timeout._onTimeout (D:\APINode\node_modules\tedious\lib\connection.js:1152:12)

=> Chưa bật SQL Server Browser

  •   Mở Services.msc → tìm SQL Server Browser → Property → Automatic → start

Thứ Hai, 3 tháng 2, 2020

Cách xử lý khi bị đụng css, load css từ cho 1 compnent

- Khi bạn muôn apply một external css cho riêng 1 component , (load từ style.css sẽ bị đụng css), thì làm như sau:
styleUrls: ['./index.component.css','../../assets/admin/dist/css/adminlte.min.css'],
encapsulation: ViewEncapsulation.None

Thứ Hai, 20 tháng 1, 2020

Các gói npm cần thiết khi sử dụng NodeJS



  • Nodemon: tự động restart lại server nodejs 
  • Tedious: Connect với mssql (Giống mssql-npm)
  • Express: frameword cho nodeJS - Giống Hapi
  • Sails: Fulltack FrameWord cho nodejs (cái này hay nè)
  • Sequilize: ORM dùng để mapping CSDL 
  • ejs: view template 
  • date-format: định dạng ngày tháng năm (Chú ý nếu cần định dạng về UTC +7 thì cần cấu hình lại trong file config hoặc connect : timezone: '+07:00',
  • dotenv: sử dụng biên môi trường .env
  • perfect-logger: Lưu log thành file .log


Sử dụng EJS làm view cho node JS

Các bước cấu hình
1. Cài đặt các gói cần thiết
#npm install --save ejs
#npm install --save bootstrap
#npm install --save jquery
#npm install --save popper

2. Tạo 1 thư mục views
- Folder: include : chưa cái file được xử dụng lại như : header, footer. nav
- 2 file: index.ejs, about.ejs
index.ejs
<!DOCTYPE html>
<html lang="en">
    <% include ('./include/head'%>
    <body>
        <% include ('./include/nav')  %>
        <div class="container">
            <div class="row">
                <h1>Home</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ('./include/scripts'%>
        <% include ('./include/footer'%>
        
    </body>
</html>
about.ejs
<!DOCTYPE html>
<html lang="en">
    <% include ('./include/head'%>
    <body>
        <% include ('./include/nav'%>
        <div class="container">
            <div class="row">
                <h1>About</h1>
            </div>
            <hr>
            <div class="row">
                <p style="height:300px;">Content Here...</p>
            </div>
        </div>

        <% include ('./include/scripts')  %>
        <% include ('./include/footer'%>
    </body>
</html>

Cầu hình app.js , do ở đây mình sử dụng chung để viết API nên sẽ cấu hình hơi khác.
const express = require('express')
const bodyParser = require('body-parser');
const path = require('path');

const app = express()

var port = process.env.HOST_PORT || 3300;

// Require static assets from public folder--------------------------- EJS
app.use(express.static(path.join(__dirname'public')));

// Set 'views' directory for any views 
// being rendered res.render()
app.set('views'path.join(__dirname'views'));

// Set view engine as EJS
app.engine('html'require('ejs').renderFile);
app.set('view engine''ejs');

//-------------------------------------------------------END EJS config

app.listen(port, () => {
    console.log("This port: " + port + " is running");
});

app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

var router = require('./routes')();
app.use('/'router);
 
//CORS Middleware
app.use(function (reqresnext) {
    //Enabling CORS 
    res.header("Access-Control-Allow-Origin""*");
    res.header("Access-Control-Allow-Methods""GET,HEAD,OPTIONS,POST,PUT");
    res.header("Access-Control-Allow-Headers""Origin, X-Requested-With, contentType,Content-Type, Accept, Authorization");
    next();
});

Tạo 1 file route.js
- Ở đây mình có require 2 file route, 1 cái của API , 1 cái của view. (API sẽ trình bày trong bày khác
const express = require('express'); 

function eRoutes() {
    const router = express.Router();
    //var employee = require('./repository/employee/employee.routes')(router);
    //var department = require('./repository/department/department.routes')(router);
    var user = require('./routes/user.routes')(router);
    var view = require('./routes/view.routes')(router);
    return router;
}

module.exports = eRoutes;

Tạo 1 thư mục route, để chưa file route
Tạo 1 file view.route.js trong thư mục route

const express = require('express');

module.exports = function (router) {
    router.get('/', (reqres=> {
        console.log('Request for home recieved');
        res.render('index');
    });

    router.get('/about', (reqres=> {
        console.log('Request for about page recieved');
        res.render('about');
    });

    router.get('/contact', (reqres=> {
        console.log('Request for contact page recieved');
        res.render('contact');
    });
}

Ok con dê: