TECH

September 13, 2024

Integrating Bloc with MVVM in Flutter

Bloc is come from a unidirectional data flow (UDF) pattern. However, if you want use Bloc in MVVM design pattern, this small post will share with you the way to get it.
The main components in MVVM model:
1. Model (M) :
   - Represents your application's data and business logic. Models should be independent of the UI and handle all data-related tasks, such as fetching data from APIs or databases.
 
2. View (V) :
   - Represents the UI of your application. The View subscribes to a Bloc to get updates and display the current state.
 
3. ViewModel (VM) :
   - In Flutter, the Bloc acts as the ViewModel. It holds the state of the UI, handles user input, and updates the state. The ViewModel interacts with the Model to fetch, update, or modify data.
 
 
The below small sample app will show how you can structure a Flutter app using Bloc in an MVVM design architecture:

 

 

 

1. Model (M):
   - A Dart class that represents your data.
 
   class User {
     final String name;
     final int age;
 
     User({required this.name, required this.age});
   }
 
 
2.  ViewModel (VM):
   - The Bloc will manage the state of the View. It consumed events and emits states.
   import 'package:bloc/bloc.dart';
 
   // Events
   abstract class UserEvent {}
 
   class LoadUser extends UserEvent {}
 
   // States
   abstract class UserState {}
 
   class UserInitial extends UserState {}
 
   class UserLoaded extends UserState {
     final User user;
 
     UserLoaded(this.user);
   }
 
   // Bloc
   class UserBloc extends Bloc<UserEvent, UserState> {
     UserBloc() : super(UserInitial()) {
       on<LoadUser>((event, emit) {
         // Simulate to fetch the user data (from a repository)
         final user = User(name: "Teddy Nguyen", age: 44);
         //Emit the new event
         emit(UserLoaded(user));
       });
     }
   }
 
3. View (V):
   - The UI part that listens to the Bloc for state changes and displays the data.
 
   import 'package:flutter/material.dart';
   import 'package:flutter_bloc/flutter_bloc.dart';
 
   class UserScreen extends StatelessWidget {
     @override
     Widget build(BuildContext context) {
       return Scaffold(
         appBar: AppBar(title: Text('User')),
         body: BlocBuilder<UserBloc, UserState>(
           builder: (context, state) {
             if (state is UserInitial) {
               return Center(child: CircularProgressIndicator());
             } else if (state is UserLoaded) {
               return Center(child: Text('Name: ${state.user.name}, Age: ${state.user.age}'));
             } else {
               return Center(child: Text('Something went wrong!'));
             }
           },
         ),
       );
     }
   }
 

(Feature image designed by rawpixel.com on Freepik)

View More
TECH

August 27, 2024

First Yocto Project Build

Have you heard of the Yocto Project? This article aims to introduce the concepts and guide you through the basic steps to get started with Yocto Project development.

View More
TECH

August 27, 2024

Understanding Code-First and Database-First in Entity Framework

When developing applications using Entity Framework (EF), choosing the right approach for designing your database is crucial. The two main strategies are Code-First and Database-First. Each has its strengths and is suitable for different scenarios. Let's delve into the details of these approaches to understand their differences and determine which might be the best fit for your project.

View More
TECH

June 17, 2024

Understanding Scope in JavaScript

Imagine scope as a boundary within which the identifiers in your JavaScript program: variables and functions.

This boundary delineates their realm of influence, dictating where they can be utilized or even recognized by the rest of your code.

View More
TECH

August 9, 2024

Benefits of using Prism + ReactiveProperty in a WPF project

Windows Presentation Foundation (WPF) is a Microsoft platform used to build graphical applications for workstations running the Windows operating system. First introduced in 2006 in the .NET Framework 3.0, WPF offers many improvements over previous Windows Forms, including the ability to build more user-friendly and dynamic user interfaces. It also provides powerful data linking capabilities and supports multimedia such as images, audio and video.

View More
TECH

August 9, 2024

.NET - Use Analyze Code Coverage for Unit Testing

Code coverage is a percentage measure of your source is tested. As an example, if you have a small application with only 4 conditional branches of code (branch a, branch b, branch c and branch d), one unit test that verifies conditional branch d will report branch code coverage of 25%. 

This article discusses the usage of code coverage for unit testing with Coverlet, a cross platform code coverage library for .NET, with support for line, branch and method coverage.

View More
TECH

August 9, 2024

When should you use SCSS?

First of all, let's find out what SCSS is?
SCSS stands for "Sassy CSS", an extension language of CSS (Cascading Style Sheets).
Overall SCSS provides additional features and improvements over traditional CSS, such as variables, nesting rules, mixins, inheritance, and many other features that make writing and managing CSS code easier and more efficient.

View More
TECH

June 22, 2024

MVP Design Pattern in iOS programming

The MVP (Model-View-Presenter) pattern is a design pattern used to separate the user interface logic from the business logic in applications. MVP helps make code easier to maintain and test. In an iOS application using Objective-C, you can organize the MVP pattern as follows:
Key Components of MVP:

1. Model

Contains the data and business logic of the application.
 
Student.h
@interface Student : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age;
@end
 
Student.m
@implementation Student
- (instancetype)initWithName:(NSString *)name age:(NSInteger)age {
self = [super init];
if (self) {
_name = name;
_age = age;
}
return self;
}
 

2. View Protocol

The View protocol will include methods to display data and may have methods to show errors or other statuses.
The presenter communicate to the related view through view protocol
 
StudentViewProtocol.h
 
@protocol StudentViewProtocol <NSObject>
- (void)showStudentName:(NSString *)name;
- (void)showStudentAge:(NSString *)age;
@end

 

3. Presenter

The Presenter communicates with the View via the StudentViewProtocol. Additionally, the Presenter needs a protocol for the View to notify user events.
 
StudentPresenter.h
 
#import "StudentViewProtocol.h"
@protocol StudentPresenterProtocol <NSObject>
- (void)onLoadStudentButtonClicked;
@end
 
@interface StudentPresenter : NSObject <StudentPresenterProtocol>
@property (nonatomic, weak) id<StudentViewProtocol> view;
- (instancetype)initWithView:(id<StudentViewProtocol>)view;
@end
 
StudentPresenter.m
 
#import "StudentPresenter.h"
#import "Student.h"
@implementation StudentPresenter
- (instancetype)initWithView:(id<StudentViewProtocol>)view {
self = [super init];
if (self) {
_view = view;
}
return self;
}
- (void)onLoadStudentButtonClicked {
// In a real application, you might fetch data from a service or database
Student *student = [[Student alloc] initWithName:@"Phuoc Nguyen" age:45];
// Format data before sending to the View
NSString *ageString = [NSString stringWithFormat:@"%ld years old", (long)student.age];
// Update the View
[self.view showStudentName:student.name];
[self.view showStudentAge:ageString];
}
@end

4. View

View contains only view-related logic
In iOS, ViewController acts as the View and is also the place where user events are notified to the Presenter.
StudentViewController.h
#import <UIKit/UIKit.h>
#import "StudentViewProtocol.h"
#import "StudentPresenter.h"
@interface StudentViewController : UIViewController <StudentViewProtocol>
@property (nonatomic, strong)id<StudentPresenterProtocol> presenter;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UILabel *ageLabel;
@property (weak, nonatomic) IBOutlet UIButton *loadStudentButton;
@end

 

StudentViewController.m
#import "StudentViewController.h"
@implementation StudentViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.presenter = [[StudentPresenter alloc] initWithView:self];
[self.loadStudentButton addTarget:self.presenter action:@selector(onLoadStudentButtonClicked) forControlEvents:UIControlEventTouchUpInside];
}
- (void)showStudentName:(NSString *)name {
self.nameLabel.text = name;
}
- {
self.ageLabel.text = age;
}
@end
 
In this example, the View notifies the Presenter when the "Load Student" button is clicked. The Presenter then processes the request, fetches data from the Model, formatsit, and updates the View. This ensures that all handling logic is separated from the View, making the code more maintainable and testable.
The class diagram:

(The post is used free image from Pexels source)
View More
TECH

June 20, 2024

Setting Up MySQL Master-Slave Replication with Docker.

In today's data management environment, ensuring database availability and scalability is critical. MySQL master-slave replication is a popular technique to achieve this, helping to distribute the workload and enhance system reliability. Combined with Docker, the process of deploying and managing this system becomes easier and more flexible. In this article, we will explore how to set up MySQL master-slave replication using Docker.

What is MySQL Master-Slave Replication?

MySQL master-slave replication is a mechanism in which data from a "master" server is automatically replicated to one or more "slave" servers. This helps distribute read load, enhance resiliency, and provide easier backups.

Setup steps

1. We need to set up the directory structure as follows.

2. Edit my.cnf file information for master and slave.

master/my.cnf

[mysqld]
socket = /var/run/mysqld/mysqld.sock
lower_case_table_names = 2
log_error=/var/log/mysql/error.log
character-set-server=utf8
collation-server=utf8_general_ci
server-id=101
binlog_format=ROW
log-bin=/var/lib/mysql/mysql-bin.log

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

slave/my.cnf

[mysqld]
socket = /var/run/mysqld/mysqld.sock
lower_case_table_names = 2
log_error=/var/log/mysql/error.log
character-set-server=utf8
collation-server=utf8_general_ci
server-id=201
binlog_format=ROW
log-bin=/var/lib/mysql/mysql-bin.log

[mysql]
default-character-set=utf8

[client]
default-character-set=utf8

3. Edit docker-compose.yml file information.

version: '3'
services:
  mysql-master:
    image: percona:ps-8.0
    volumes:
      - ./master/data:/var/lib/mysql
      - ./master/my.cnf:/etc/my.cnf
    environment:
      TZ: Asia/Tokyo
      MYSQL_USER: master
      MYSQL_PASSWORD: Master123@
      MYSQL_ROOT_PASSWORD: Mastermaster123

  mysql-slave:
    image: percona:ps-8.0
    container_name: mysql-slave
    volumes:
      - ./slave/data:/var/lib/mysql
      - ./slave/my.cnf:/etc/my.cnf
    environment:
      TZ: Asia/Tokyo
      MYSQL_USER: slave
      MYSQL_PASSWORD: slave123@
      MYSQL_ROOT_PASSWORD: slaveslave123

4. Start 2 servers:

docker compose up -d

5. Wait for the process of building the container to be done successfully.

After that, check the process with the command:

docker-compose ps

6. Enter the "mysql-master" container to set the replication DB on the master server:

docker-compose exec mysql-master bash

7. Login to mySQL by the root account:

mysql -u root -pMastermaster123

8. Check the binary log whether enabled successfully or not:

SHOW VARIABLES LIKE 'log_bin';

You must make sure the status of the binary is ON before processing the next step.

9. Create a new user in order to the slave server can access to the master server and check the binary log.

Use the below command to create the 'replication' user.

CREATE USER 'replication'@'%' IDENTIFIED BY 'Slaverepl123';

10. Grant user replication access to allow creation for MySQL replications:

GRANT REPLICATION SLAVE ON *.* TO 'replication'@'%';

11. Confirm whether the grants of the user were successful or not:

SHOW GRANTS FOR replication@'%';

12. Confirm the status of the binary log on the master server:

SHOW MASTER STATUS\G

You need to save the File and Position.
We will use these values to set on the slave server.

13. Enter the "mysql-slave" container to set the replication DB on the slave server:

docker-compose exec mysql-slave bash

14. Login to mySQL by the root account:

mysql -u root -pslaveslave123

15. Execute the SQL command so it can read the binary log for any changes on the master server and make it the same on the slave server.

We will set the value of the MASTER_LOG_FILE and MASTER_LOG_POS by the value obtained from step 12.

CHANGE MASTER TO
MASTER_HOST='mysql-master',
MASTER_USER='replication',
MASTER_PASSWORD='Slaverepl123',
MASTER_LOG_FILE='binlog.000003',
MASTER_LOG_POS=1161;

16. Let’s start the slave on mysql:

START SLAVE;

17. Confirm the status of the replication on the slave server:

SHOW SLAVE STATUS\G

If the Slave_IO_State is "Waiting for source to send event" then we have set up successfully.

From now on, if the master server changes anything, it also changes on the slave server.

18. Confirm synchronization between the two databases.

Check all databases on the master/slave server.

SHOW DATABASES;

Create a new database on the master server and re-check all databases on the master server.

CREATE DATABASE replicate_db;

A new database has been created on the master server and it has also been created on the slave server.

Conclusion

With the use of Docker, setting up MySQL master-slave replication becomes much simpler and faster. This not only improves data management but also provides an easy environment for testing and development. Try implementing this system for your project to see its obvious benefits.

Using Docker to manage MySQL replication helps you take advantage of the benefits of containerization, such as easily deploying, scaling, and managing complex database systems efficiently.

References:

View More
TECH

June 20, 2024

Web Camera Issues on Devices: Troubleshooting Tips

Recently, projects involving device interactions, such as with cameras and audio, have become popular. I just
completed a project using a device's camera, and encountered some challenges that required significant effort to
overcome. To assist with your current or future projects that utilize a device's camera, I decided to write this
blog. It discusses some common issues encountered when working with cameras, and provides solutions to these
problems. I hope this will promptly resolve your current issues and prevent similar problems in your future
projects.

View More
1 2 3 9