Vuejs Watch to Trigger API

Use watch to trigger API calls when a value changes under specific conditions.
<template>
  <div>
    <input v-model="username" placeholder="Enter username" />
    <p v-if="error">{{ error }}</p>
  </div>
</template>

<script>
import { ref, watch } from 'vue';
import axios from 'axios';

export default {
  setup() {
    const username = ref('');
    const error = ref('');

    // Watch the username and make an API call when it changes
    watch(username, async (newUsername) => {
      if (newUsername.length >= 3) {
        try {
          const response = await axios.get(`/api/check-username?username=${newUsername}`);
          if (!response.data.available) {
            error.value = 'Username is already taken';
          } else {
            error.value = '';
          }
        } catch (err) {
          error.value = 'Error checking username';
        }
      } else {
        error.value = 'Username must be at least 3 characters long';
      }
    });

    return { username, error };
  },
};
</script>

Vuejs Watching Route Changes

use watch to monitor changes to the current route and react accordingly (e.g., fetch new data when a different page is navigated to).
<script>
import { watch } from 'vue';
import { useRoute } from 'vue-router';

export default {
  setup() {
    const route = useRoute();

    // Watch for changes in the route params or query
    watch(route, (newRoute, oldRoute) => {
      console.log('Route changed:', newRoute.path);
      // trigger a function or fetch data based on the new route
    });

    return {};
  },
};
</script>

Vuejs Watching Form Input Validation

use watch to monitor form input fields and validate them in real-time.
<template>
  <div>
    <label>Email:</label>
    <input v-model="email" type="email" />
    <span v-if="emailError">{{ emailError }}</span>
  </div>
</template>

<script>
import { ref, watch } from 'vue';

export default {
  setup() {
    const email = ref('');
    const emailError = ref('');

    // Watch email input for changes and validate it
    watch(email, (newEmail) => {
      const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
      if (!emailPattern.test(newEmail)) {
        emailError.value = 'Invalid email format';
      } else {
        emailError.value = '';
      }
    });

    return { email, emailError };
  },
};
</script>

JS Default Object With Object Assign

Default objects with Object.assign
const menuConfig = {
  title: "Order",
  buttonText: "Send",
  cancellable: true
};

function createMenu(config) {
  config = Object.assign(
    {
      title: "Foo",
      body: "Bar",
      buttonText: "Baz",
      cancellable: true
    },
    config
  );

  // config now equals: {title: "Order", body: "Bar", buttonText: "Send", cancellable: true}
}

createMenu(menuConfig);

// bad code [X]
function createMenu(config) {
  config.title = config.title || "Foo";
  config.body = config.body || "Bar";
  config.buttonText = config.buttonText || "Baz";
  config.cancellable =
    config.cancellable !== undefined ? config.cancellable : true;
}

Git Change Author Commit

a shell function to change the author of a git commit.
// add below function to ~/.zshrc (or ~/.bash_profile in Linux or older version Macos )

function commitas {
  export GIT_COMMITTER_NAME=$1
  export GIT_COMMITTER_EMAIL=$2
  git commit --author="$GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" -m $3
}

// terminal
source ~/.zshrc

Go to folder repository, git add your changing.

Now simply run

commitas "BBMCode" "test@bbmcode.com" "Do something"

PHP Sorting an array by multiple fields

sort multiple arrays or an array of associative arrays by different fields using array_multisort.
// Sorting an array by multiple fields
$people = [
    ['name' => 'John', 'age' => 28, 'city' => 'New York'],
    ['name' => 'Alice', 'age' => 24, 'city' => 'Los Angeles'],
    ['name' => 'Bob', 'age' => 32, 'city' => 'Chicago'],
    ['name' => 'Charlie', 'age' => 24, 'city' => 'San Francisco']
];

// Create arrays for the fields you want to sort by
$age = array_column($people, 'age');
$name = array_column($people, 'name');

// Use array_multisort to sort by age (ascending) and then by name (ascending)
array_multisort($age, SORT_ASC, $name, SORT_ASC, $people);

print_r($people);

// output
Array
(
    [0] => Array
        (
            [name] => Alice
            [age] => 24
            [city] => Los Angeles
        )

    [1] => Array
        (
            [name] => Charlie
            [age] => 24
            [city] => San Francisco
        )

    [2] => Array
        (
            [name] => John
            [age] => 28
            [city] => New York
        )

    [3] => Array
        (
            [name] => Bob
            [age] => 32
            [city] => Chicago
        )
)

// Sorting by multiple fields with different sort orders
$people = [
    ['name' => 'John', 'age' => 28, 'city' => 'New York'],
    ['name' => 'Alice', 'age' => 24, 'city' => 'Los Angeles'],
    ['name' => 'Bob', 'age' => 32, 'city' => 'Chicago'],
    ['name' => 'Charlie', 'age' => 24, 'city' => 'San Francisco']
];

// Create arrays for age and name
$age = array_column($people, 'age');
$name = array_column($people, 'name');

// Sort by age descending and by name ascending
array_multisort($age, SORT_DESC, $name, SORT_ASC, $people);

print_r($people);

// output
Array
(
    [0] => Array
        (
            [name] => Bob
            [age] => 32
            [city] => Chicago
        )

    [1] => Array
        (
            [name] => John
            [age] => 28
            [city] => New York
        )

    [2] => Array
        (
            [name] => Alice
            [age] => 24
            [city] => Los Angeles
        )

    [3] => Array
        (
            [name] => Charlie
            [age] => 24
            [city] => San Francisco
        )
)

Vuejs Axios Call Api

The best practices for API calls in Vue.js 3 Composition API.
// src/services/apiService.js
import axios from 'axios';

const apiClient = axios.create({
  baseURL: 'https://jsonplaceholder.typicode.com',
  timeout: 1000,
  headers: { 'Content-Type': 'application/json' },
});

// Define your API methods
export default {
  getUsers() {
    return apiClient.get('/users');
  },
  getUser(id) {
    return apiClient.get(`/users/${id}`);
  },
};


// src/composables/useFetchUsers.js
import { ref } from 'vue';
import apiService from '../services/apiService';

export function useFetchUsers() {
  const data = ref(null);
  const loading = ref(false);
  const error = ref(null);

  const fetchUsers = async () => {
    loading.value = true;
    try {
      const response = await apiService.getUsers();
      data.value = response.data;
    } catch (err) {
      error.value = 'Error fetching users';
    } finally {
      loading.value = false;
    }
  };

  return { data, loading, error, fetchUsers };
}


// src/components/UsersComponent.vue
<template>
  <div>
    <button @click="fetchUsers">Load Users</button>
    <div v-if="loading">Loading...</div>
    <ul v-if="data">
      <li v-for="user in data" :key="user.id">{{ user.name }}</li>
    </ul>
    <div v-if="error">{{ error }}</div>
  </div>
</template>

<script>
import { onMounted } from 'vue';
import { useFetchUsers } from '../composables/useFetchUsers';

export default {
  setup() {
    const { data, loading, error, fetchUsers } = useFetchUsers();
    
    onMounted(() => fetchUsers()); // Fetch users when the component is mounted

    return { data, loading, error, fetchUsers };
  },
};
</script>

// src/main.js
import { createApp } from 'vue';
import App from './App.vue';
import UsersComponent from './components/UsersComponent.vue';

createApp(App)
  .component('UsersComponent', UsersComponent)
  .mount('#app');
src/
├── composables/
│   └── useFetchUsers.js   # Composable for fetching users
├── services/
│   └── apiService.js      # Centralized API service layer
├── components/
│   └── UsersComponent.vue # Component using the API and composable
└── main.js                # Main entry point for Vue app

PHP Convert Vietnamese Without Diacritics

Convert Vietnamese text with diacritics to plain text (without diacritics). Useful for friendly URL
function convertVItoEN($str) {
    $str = preg_replace("/(à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ)/", "a", $str);
    $str = preg_replace("/(è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ)/", "e", $str);
    $str = preg_replace("/(ì|í|ị|ỉ|ĩ)/", "i", $str);
    $str = preg_replace("/(ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ)/", "o", $str);
    $str = preg_replace("/(ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ)/", "u", $str);
    $str = preg_replace("/(ỳ|ý|ỵ|ỷ|ỹ)/", "y", $str);
    $str = preg_replace("/(đ)/", "d", $str);
    $str = preg_replace("/(À|Á|Ạ|Ả|Ã|Â|Ầ|Ấ|Ậ|Ẩ|Ẫ|Ă|Ằ|Ắ|Ặ|Ẳ|Ẵ)/", "A", $str);
    $str = preg_replace("/(È|É|Ẹ|Ẻ|Ẽ|Ê|Ề|Ế|Ệ|Ể|Ễ)/", "E", $str);
    $str = preg_replace("/(Ì|Í|Ị|Ỉ|Ĩ)/", "I", $str);
    $str = preg_replace("/(Ò|Ó|Ọ|Ỏ|Õ|Ô|Ồ|Ố|Ộ|Ổ|Ỗ|Ơ|Ờ|Ớ|Ợ|Ở|Ỡ)/", "O", $str);
    $str = preg_replace("/(Ù|Ú|Ụ|Ủ|Ũ|Ư|Ừ|Ứ|Ự|Ử|Ữ)/", "U", $str);
    $str = preg_replace("/(Ỳ|Ý|Ỵ|Ỷ|Ỹ)/", "Y", $str);
    $str = preg_replace("/(Đ)/", "D", $str);
    $str = str_replace(" ", "-", str_replace("&*#39;","",$str));
    return strtolower($str);
    // thật hữu ích -> that-huu-ich
}

Js Sort Array Object

Sort an array of objects by property in JavaScript
// Sorting by a String Property
const people = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "Charlie", age: 35 }
];

people.sort((a, b) => a.name.localeCompare(b.name));

console.log(people);
// Output: [{ name: "Alice", age: 30 }, { name: "Bob", age: 25 }, { name: "Charlie", age: 35 }]

// Sorting by a Numeric Property
const people = [
  { name: "Alice", age: 30 },
  { name: "Bob", age: 25 },
  { name: "Charlie", age: 35 }
];

people.sort((a, b) => a.age - b.age);

console.log(people);
// Output: [{ name: "Bob", age: 25 }, { name: "Alice", age: 30 }, { name: "Charlie", age: 35 }]

// Sorting by a Date Property
const events = [
  { title: "Event 1", date: new Date('2023-09-01') },
  { title: "Event 2", date: new Date('2023-08-01') },
  { title: "Event 3", date: new Date('2023-07-01') }
];

events.sort((a, b) => a.date - b.date);

console.log(events);
// Output: [{ title: "Event 3", date: 2023-07-01 }, { title: "Event 2", date: 2023-08-01 }, { title: "Event 1", date: 2023-09-01 }]

// Sorting in Descending Order
people.sort((a, b) => b.age - a.age);

console.log(people);
// Output: [{ name: "Charlie", age: 35 }, { name: "Alice", age: 30 }, { name: "Bob", age: 25 }]