Skip to main content

7 Reasons why Golang is the best backend programming language

· 4 min read
Ali Torabi

In case you never heared Golang before, it is a staticly typed, compiled language, which is developed by google to reduce their need for C/C++ in web area. This language has some benefits over C/C++ besides seems to be true winner win I compared it to other programming languages that I've worked with, such as PHP, C# and Node.js

Golang can be compiled for major OS available out there, plus some microcontrollers using TinyGo and mobile applications, using Gomobile project. Today I am going to tell you the 8 major reasons we prefer go for our projects and clients.

1. Golang has a simple syntax

When you compare Golang with Java and C++, you just realize there are much lesser features in the language, No OOP, and many flavors and options. In first glance all those tools seem to be handy, but for major use cases they are not needed and only tend to complicated source code of a project, specially if it was borrowed or it's a legacy code.

This means faster development, and easier for new developers to learn and join the project.

2. Golang produces binary files

Hell yeah. When you are writting code in Node.js or Python, you always need the installation, dependency management and deploying issues because they are scripts.

A well written Golang application, can be compiled into binary files (exe on Windows!) and it would be expected to run for next few decases, without any changes.

3. High performance, small memory footprint

When you write a node.js app, just in order to run it, you need to have somewhat serious mashine to run it, and right away gets a lot of memory and cpu usage even for a hello world app. Golang binaries for small web applications are around 10-30 MB in a single executable file.

Comparing this to a Java web application, which right away needs 4GB of ram to run, and constantly needs hardware upgrade and code maintenance while the server loads increases, might make you realize you could have better weekends writing those applications into something C-level performant.

4. CommandLine and WebServer together.

Using golang you can create binary, which can both start a web server, as well as run in cli as a command line tool. In fact, major and long-lasting projects are simple executables, which provide command line interface to developers and include a help for each action.

In large projects which have a lot of calculations, Web server is only a layer that maps requests to these binary files. Mostly, these layers and separation is not designed due to convenience of MVC frameworks, and the software assumed completely a web flow instead of logic base and presentation layet.

5. Signing and Notarization

Golang is a proper binary, you can sign it's binaries for Windows and MacOs without any problems. In fact, bundling a node.js app into an executable file and run it next to an Electron app, caused an MVP to fail in our past.

6. Different build target

You can create different version of your application using targetting, which gives you the option not only to market for different people, but not to distribute code which is not needed for all clients.

In case of creating a well built binary, (for example our FireBack product) you can bundle those into many applications and distribute it several times.

7. Golang is not that scary.

Many people tend to prefer Python and Node.js because of their scripting simplicity, or re-use the knowledge in web development on the backend side. This tend to generate unportable projects, which usually have very short lifespan, and need constant maintanance. Learning Golang is not that hard, and you can create CLI apps and Web apps much easier than you think.

ATS-01 Standard for React Native List based projects

· 3 min read
Ali Torabi

ATS-01 is a set of rules, which will be granted into any list, if it meets certain level of the conditions. Lack of quality in many products which we see, is due to missing full implementation of these rules. You might already have this rules available in your app - therefor no need to make adjustments just to use this document as reference.

Technologies: React Native

Programming Languages: JavaScript/TypeScript

Why the lists are important?

Mobile applications are built heavily around lists. In a mobile device, user is usually swiping vertically and less often horizontally. Thus, software companies need to focus on building better lists which interacts more smoothly.

Conditions to meet ATS-01

Here is the interactive list of ATS-01 standard. ATS-01 is met when the screen must implement or be implemeneted:

  • Only in React Native framework
  • By FlatList or other virtual list
  • Error handling for first-fetch strategy
  • Error handling when a set of data is present to the user
  • Empty list strategy
  • Pagination
  • Skeleton loader
  • Taking too long indication
  • Timeout and retry mechanism
  • Request cancellation on leaving the screen

Only in React Native framework

The application needs to be written in React Native. Android/IOS/Ionic/Xamarin and etc are not accpted in this standard.

By FlatList or other virtual list

Starndard only applies to screens which need to show dataset, usually from remote service or bluetooth, WIFI devices. It does not apply to stationary elements, which are put in ScrollView

Examples:

  • List of posts
  • List of images
  • Bluetooth devices around

Error handling for first-fetch strategy

Screen needs to have a clear strategy, to show the errors occured while fetching information from remote, or any other permission issues, requirement in the first list.

Error handling when a set of data is present to the user

Screen should handle in case of subsequent failures of fetching data, or changes to parameters, and show them on top of the list, as header and give user clear action point to move next steps.

Empty list strategy

Screen needs to clearly give user feedback if the remote list is empty. It should be different than network failures, other impediments precluding user to understand real data availabilty.

Pagination

The screen should load the data from it's remote based on user scroll threshold. Even if the remote source does not have such possiblity, you need to make a PaginatableArray out of it pass it to this component.

Skeleton loader

On the first pull, you need to have skeleton porportional to the real items implemented. User should not see a loader, while the screen is opened first time.

Taking too long indication

In case loading of data is taking longer than usual, there should be indication of that, tell the user that they can cancel or retry in specific amount of time.

Timeout and retry mechanism

It should be giving user message "Pull to retry" in case of failure in first or subsequent requests.

Request cancellation on leaving the screen

Screen needs to keep an strategy to clean up remote requests, BLE scanning, or any ongoing process to provide data in to screen, in case user tried to leave the screen.

Honest comparision of hybrid app vs. Native finally

· 12 min read
Ali Torabi

When considering the development of an app for your idea or business needs, you'll inevitably confront a pivotal question: whether to pursue a hybrid or native approach. In the internet there are many biased comparison, and after 20 years of being active in software industry and coding for many different companies, clients and projects I want to enlight this issue once for all.

If you want build an app, I invite you to be patient, and read this article completely which might save you years of hassle

For those just beginning to contemplate app development with little knowledge of where to start, it's worth noting that there exist several avenues (setup, ecosystem, or development framework) for building mobile apps. Some opt for the native route, utilizing platform-specific tools, while others embrace a hybrid approach, which overlays a layer enabling the use of a single codebase across multiple platforms, such as Android and iOS.

In this article and accompanying video, we'll delve into the considerations for choosing the optimal approach for your next application, whether you're collaborating with a development team or embarking on the journey solo.

  • Understanding the distinctions between native and hybrid development
  • How do I build cost-effective 2 native apps over other agencies
  • Overview of tools commonly employed for Android Native, iOS Native, and prevalent hybrid technologies
  • Strategies for selecting the most suitable technology stack for your app
  • How to start building your new app?

How do I build cost-effective 2 native apps over other agencies

Internally, I use a large and significant project called Fireback to serve clients. Fireback aims to accelerate the development process for native Android and iOS apps by providing several key features and tools. Here's how Fireback can expedite the creation of native apps compared to manual development:

  • Code Generation: Fireback offers powerful code generation tools that automate the creation of boilerplate code for Android and iOS apps. By defining the data model and business logic in a Module2 file, Fireback can generate the necessary code for models, API clients, and other components of the app.
  • Integrated SDKs: Fireback provides integrated SDKs for Android and iOS that simplify the process of integrating the backend with the native apps. These SDKs handle communication with the backend API, data serialization, authentication, and other tasks, reducing the amount of manual coding required.
  • Standardized Architecture: Fireback promotes a standardized architecture for native apps, ensuring consistency and maintainability across different platforms. By adhering to best practices and conventions, developers can build robust and scalable apps more efficiently.
  • Prebuilt Components: Fireback includes prebuilt components and templates for common app features such as user authentication, data fetching, and UI components. Developers can leverage these components to quickly assemble the app's functionality without starting from scratch.
  • Cross-Platform Support: While Fireback focuses on native Android and iOS development, it also supports cross-platform frameworks like React Native and Flutter. Developers can use Fireback to generate code for these frameworks, further accelerating the development process and enabling code reuse across platforms.

Overall, Fireback streamlines the development of native Android and iOS apps by automating repetitive tasks, providing standardized solutions, and integrating seamlessly with the backend. By leveraging Fireback's features and tools, developers can build high-quality apps faster and more efficiently than manual development methods.

Understanding the distinctions between native and hybrid development

Native and hybrid app development are two prevalent approaches for creating mobile applications, each offering unique advantages and considerations. In native app development, developers utilize platform-specific languages and tools such as Swift for iOS and Android Java for Android to build applications tailored specifically for a single operating system. This approach maximizes performance, integration with device features, and adherence to platform guidelines, resulting in a polished user experience. On the other hand, hybrid app development leverages web technologies like JavaScript, HTML, and CSS within frameworks such as React Native, React Cordova, Flutter, and Xamarin to enable cross-platform compatibility. While hybrid apps can expedite development and reduce costs by sharing a single codebase across multiple platforms, they may sacrifice some performance and platform-specific optimizations. Each approach presents its own set of trade-offs, and the choice between native and hybrid development depends on factors such as project requirements, budget, and target audience.

Hybrid apps, while offering cross-platform compatibility and potential cost savings in development, often incur higher maintenance costs due to several factors. One significant contributor is the quality of JavaScript and the hybrid framework itself. Unlike native solutions which are optimized for specific platforms, hybrid apps rely on web technologies wrapped within a framework to function across multiple platforms. This abstraction layer can introduce performance inefficiencies and compatibility issues, necessitating ongoing maintenance efforts to address bugs, optimize performance, and ensure compatibility with platform updates. Consequently, businesses opting for hybrid development should carefully consider the long-term maintenance implications and allocate resources accordingly to mitigate potential challenges and ensure the continued success of their apps.

Performance:

  • Native apps are typically faster and more responsive because they are specifically optimized for the platform they are built for (iOS or Android). They have direct access to device-specific features and can leverage the full potential of the device's hardware.
  • Hybrid apps, on the other hand, often rely on a web view component to render their user interface, which can introduce some performance overhead compared to native apps. However, advancements in hybrid frameworks have narrowed this performance gap significantly.

User Experience:

  • Native apps provide a seamless user experience consistent with the platform's design guidelines. They can take advantage of native UI components and animations, resulting in a polished look and feel.
  • Hybrid apps may not always offer the same level of user experience as native apps. While they can mimic the appearance of native apps to some extent, they may not fully replicate the platform-specific behaviors and interactions.

Development Time and Cost:

Native app development often requires separate codebases for each platform (Objective-C/Swift for iOS, Java/Kotlin for Android), which can increase development time and cost, especially if the app needs to be maintained for multiple platforms. Hybrid app development allows developers to write code once and deploy it across multiple platforms, potentially reducing development time and cost. However, achieving feature parity across platforms and optimizing performance may require additional effort.

Access to Device Features:

  • Native apps have direct access to device features such as camera, GPS, accelerometer, and contacts, allowing developers to create rich, immersive experiences that leverage these capabilities.
  • Hybrid apps can access device features through plugins or APIs provided by hybrid frameworks. While many device features are accessible, there may be limitations or delays in implementing support for new features compared to native development.

Final decision for native or hybrid

In the long run, investing in native technologies often proves to be a more prudent choice, particularly for apps with critical functionalities requiring regular updates, or for businesses heavily reliant on the quality of their applications. Native solutions offer several advantages, including superior performance, seamless integration with platform features, and access to a larger talent pool for ongoing maintenance and feature enhancements. This ensures the longevity and scalability of your app, especially if you plan to establish an in-house development team in the future.

However, for those embarking on their journey or seeking to experiment with a more flexible approach, a hybrid solution can still be viable. Utilizing frameworks like React Native, I can assist you in building a high-quality app that balances cross-platform compatibility with performance and user experience. Whether you choose native or hybrid development, my goal remains consistent: to deliver the best possible solution tailored to your unique needs and aspirations.

Overview of tools commonly employed for Android Native, iOS Native, and prevalent hybrid technologies

While there are numerous technologies available for app development, I want to focus on the mainstream here which are common (sorted from most common to least)

For Apple Devices (Native)

Xcode and Swift form the backbone of iOS app development, offering a comprehensive suite of tools and resources for building native applications exclusively for Apple's ecosystem. Xcode serves as the integrated development environment (IDE), providing features such as code editing, debugging, and interface design. Swift, Apple's modern programming language, is known for its safety, performance, and ease of use. With its concise syntax and powerful features, Swift enables developers to write clean, efficient code while leveraging iOS-specific frameworks for seamless integration with device features like Touch ID, ARKit, and Core ML.

For Android Devices (Native)

Android Java, coupled with the Android SDK, constitutes the foundation of Android app development. Java serves as the primary programming language, offering robust support for object-oriented programming and a vast ecosystem of libraries and frameworks. The Android SDK provides tools for designing user interfaces, accessing device hardware, and managing app resources. Developers can harness the extensive capabilities of Android Java to create feature-rich applications that leverage platform-specific functionalities like notifications, background services, and deep linking.

React Native (Many devices)

React Native revolutionizes mobile app development by enabling the creation of cross-platform applications using JavaScript and React. Leveraging a single codebase, developers can build apps for both iOS and Android platforms, saving time and resources. React Native utilizes native components under the hood, resulting in high-performance apps with native look and feel. Its hot reloading feature allows for real-time code changes, enhancing productivity during development. Additionally, the vibrant React Native community provides a wealth of third-party libraries and tools for extending functionality and solving common development challenges.

React.js with Webview (Cordova, Android and IOS Devices)

Embedding React.js with Cordova facilitates the creation of hybrid mobile applications using web technologies like HTML, CSS, and JavaScript. Cordova acts as a bridge, enabling web applications to access native device capabilities through plugins. By embedding React.js within a Cordova project, developers can leverage the power of React's component-based architecture and declarative syntax to build interactive user interfaces. Cordova's extensive plugin ecosystem provides access to a wide range of device features, enabling developers to create hybrid apps with native-like functionality and performance.

Flutter (Complete new system for multiple platfroms)

Flutter, Google's UI toolkit for building natively compiled applications, enables developers to create beautiful, fast, and expressive apps for iOS, Android, and the web from a single codebase. Flutter employs Dart, a modern, object-oriented programming language, renowned for its simplicity, productivity, and performance. With Flutter's reactive framework and extensive widget library, developers can craft highly customizable user interfaces with smooth animations and seamless scrolling. Hot reload functionality accelerates iteration cycles, enabling rapid prototyping and iteration, while Flutter's rich ecosystem of packages and plugins extends functionality and enhances developer productivity.

Xamarin (C# developer friendly)

Xamarin empowers developers to build cross-platform mobile applications using C# and the .NET framework. Leveraging a shared codebase, developers can target multiple platforms, including iOS, Android, and Windows, while maintaining native performance and user experience. Xamarin.Forms simplifies UI development by providing a common abstraction layer for creating user interfaces that render natively on each platform. Additionally, Xamarin's tight integration with Visual Studio and Xamarin Test Cloud streamlines development, debugging, and testing workflows, accelerating time to market and reducing development overhead.

Strategies for selecting the most suitable technology stack for your app

Choosing the appropriate framework largely depends on the individual or team and the company's circumstances. For instance, if you possess a proficient React Native team or a team skilled in web development and aim to release a moderately critical app swiftly, React Native might be an optimal choice. Leveraging my extensive experience in React Native app development, coupled with AI code generation tools and a robust backend system, I've successfully built apps in as little as a week, ready for store deployment.

Conversely, for established businesses prioritizing market competitiveness, availability, performance, and long-term maintenance, I recommend developing two separate native apps tailored to the specific needs of their target audience. While the development pace may not match that of a single codebase like React Native, my simultaneous work on Android and iOS ensures efficient development, supported by a wealth of components, experience, code generation tools, and pre-solved business logics, mitigating any perceived slowdowns.

Moreover, when teams comprise more than one individual per app, the discrepancy between native and hybrid development diminishes, particularly when utilizing the Firebase framework.

Another scenario where a single native app may prove more advantageous is when developing a tool for installers or a stationary app for specific devices, sometimes exclusively for one platform. Maintaining a native Android or iOS app, although it may seem costlier upfront, ultimately proves more economical than hybrid alternatives. Additionally, native development grants greater control over intricate details, which may require extensive effort to implement in hybrid systems.

How to start building your new app?

If you're considering building an app, I'm here to assist you in getting started. Feel free to reach out to me directly at ali-torabian@outlook.com with your proposal. Be sure to document your ideas thoroughly, detailing your vision for the app and explaining the underlying business concept. Let's connect and bring your app idea to life!

Additionally, if you're a developer venturing into mobile app development for the first time, I recommend checking out https://github.com/torabian/fireback. There, you'll discover a comprehensive boilerplate and a suite of tools designed to expedite and streamline your startup journey, ensuring reliability and scalability without the need for frequent rewrites. Dive in and kickstart your mobile app development journey with confidence!

Stop Chaos! Angular Translations Done Right Once

· 7 min read
Ali Torabi

Critical problems with ng translate, i18n and others

The significance of translations appears to be overlooked, with the second language often treated as an afterthought in my projects; some even begin with non-English strings hardcoded in templates, only to encounter challenges later when attempting to modify them, as the lack of type safety prevents immediate detection of all occurrences, resulting in an inconsistent user experience where English words may unexpectedly appear in a Spanish interface, negatively impacting the brand's reputation.

The ng translate module, while initially a convenient tool for handling translations in Angular apps, often falls short in several key areas. One prevalent issue is the prevalence of hardcoded strings within templates, making it challenging to maintain and update translations efficiently. Additionally, the lack of IntelliSense support hampers developers' productivity, leading to potential errors and inconsistencies in translations. Moreover, the module's limited capabilities for managing different languages result in cumbersome workflows and difficulties in maintaining language-specific content.

Another significant drawback is the cumbersome process of storing translations in separate JSON files, which can lead to cluttered project structures and version control issues. These challenges collectively contribute to a suboptimal translation experience, urging developers to seek alternative solutions for their localization needs.

Solution is simple; And no library is needed

In fact, doing a bullet proof translation mechanism for Angular projects does not need another library at all. In this tutorial we are going to solve this with two items:

  • Base component for all components in the app
  • LocaleService which will be handling changes to language and publishing it everywhere

What you need before

You can apply what you learn here to new projects, as well as your existing project

  • In order to keep up with the training, you need an empty angular 2+ project. I am using most recent version here, which has 'standalone' components, but if you are using older version of Angular, there would be no difference.

  • Install fireback v1.1.9 or later. You can find the binaries for different systems here: https://github.com/torabian/fireback/releaseshttps://github.com/torabian/fireback/releases for installers.

  • I use the VSCode, and Run On Save extension is enabled. You can run the translation from CLI as well, but having this extension makes life easier by far.

Step 1: Verify you have access to fireback

You need to make sure you have access to fireback binary, either installed globally, or you put it in the project directory, and ignored the file.

Step 2: Create the LocaleService

Here's the revised version:

The LocaleService is a simple service that would be used almost everywhere in the project, with one purpose: to keep and sync the locale data.

In this service, there is an observable called locale$ which we will subscribe to in the component to change the dictionary of translation variables. Additionally, there is a setLocale function to set the language. For example, setLocale('en') would change it to English.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
providedIn: 'root',
})
export class LocaleService {
private localeSubject = new BehaviorSubject<string>('en');
locale$ = this.localeSubject.asObservable();

constructor() {}

setLocale(locale: string) {
this.localeSubject.next(locale);
}
}

Step 3: Create a base component

Creating a base component is a powerful feature of Angular and TypeScript, which makes it easy to extend some core features for every component in your project. If you already have such a component in your project, you can apply the code here to that. If you're starting fresh, create a new component called base.component.ts.

Important: You need to use @Directive instead of @Component decorator; otherwise, Angular will not compile it.

Firstly, we need a variable, such as s, to hold the key translations for the template or the component. It will be protected so that extending classes can actually access it, as well as the template file.

Then, we need to inject the LocaleService and an object of translation keys upon construction. This object will hold translations for all languages (as you will see later after we generate the translations.ts file). In this constructor, we will call a handleLocale function, which is basically a subscription to the locale, and will replace the dictionary of s content with the selected language."

Step 4: Create 'strings' folder

How you organize the translations is up to you, in fact. I prefer to create a strings folder per module and place all of their translations into that directory. This way, when I move a module folder to another project or if I want to make it a library, I won't have to worry about the translations; they're already solved and attached to the component or module.

On the other hand, if you want to create a strings folder for the entire app, nothing would stop you.

Step 5: Create strings/strings-en.yml

It's critical to keep in mind that the Fireback Language Editor module assumes English as the primary language of the app. Simply put, English must be present, and other languages will be synced with keys from that one.

Now, let's put the content inside the YAML. All translation keys must go under the content key, otherwise they will not be considered translations.

If you are not familiar with YAML, think of it as JSON without quotes, and remember:

content:
loading: Loading...
done: Done :)

Is different from the code below. (Basically intention is super important)

content:
loading: Loading...
done: Done :)

So far, this was all the necessary steps we needed to take for translating our app.

Step 6: Use and config fireback language generator

Now we need to use the Fireback language generator to simplify key generation for us.

fireback gen strings --path ./src/app/components/loader-sample/strings/strings-en.yml --targets ts --langs pl,fa

This command will generate two additional files in the same directory: strings-pl.yml and strings-fa.yml. If you open them, you will see identical content to your strings-en.yml.

Also in the same directory, you will find a translations.ts file. It contains content similar to the snippet below, which has generated TypeScript constants for all three languages and exported them as strings.

Step 7: Make this automated with VSCode run-on-save

Using the CLI each time for building the translations is cumbersome. Therefore, we utilize the "Run on save" extension in VSCode, which you can install.

Then, in our settings.json in VSCode, we need to add these rules. (If you've never modified this file, create a folder named .vscode at the root of your project and add settings.json inside it.)

{
"emeraldwalk.runonsave": {
"commands": [
{
"match": "strings-([a-z][a-z]).yml$",
"cmd": "fireback gen strings --path ${file} --langs en,fa"
}
]
}
}

It would basically detect any strings-xx.yml change in the project, and will run strings compiler for you.

Step 8: Use translations

At this stage, we're essentially ready to utilize the translation file. In any component that extends from BaseComponent, you'll be able to pass strings and access the s variable both inside the component and in the template.

import { Component } from '@angular/core';
import { BaseComponent } from '../base.component';
import { LocaleService } from '../../locale.service';
import { strings } from './strings/translations';

@Component({
selector: 'app-loader-sample',
standalone: true,
imports: [],
templateUrl: './loader-sample.component.html',
styleUrl: './loader-sample.component.scss',
})
export class LoaderSampleComponent extends BaseComponent {
override s = strings;
constructor(private locale: LocaleService) {
super(locale, strings);
}
}

And you can access s and all the keys type-safely in HTML templates. As you've noticed, we actually do not need to pipe the translations at all, and this is a significant benefit both in terms of performance and code cleanliness.

<p>{{ s.loading }}</p>

Conclusion

To summarize, we have just created a robust system for adding translations to our Angular app. This method will help prevent many errors, such as missing keys in certain languages and hard-coded strings for translation.

The Fireback Strings CLI offers additional options that you may want to explore on your own. This feature is available starting from Fireback v1.1.9

Stop Chaos! React & React Native Translations Done Right Once

· 7 min read
Ali Torabi

Critical problems with usual react translation libraries, i18n and others

The significance of translations appears to be overlooked, with the second language often treated as an afterthought in my projects; some even begin with non-English strings hardcoded in templates, only to encounter challenges later when attempting to modify them, as the lack of type safety prevents immediate detection of all occurrences, resulting in an inconsistent user experience where English words may unexpectedly appear in a Spanish interface, negatively impacting the brand's reputation.

The i18n module, while initially a convenient tool for handling translations in React and React Native apps, often falls short in several key areas. One prevalent issue is the prevalence of hardcoded strings within templates, making it challenging to maintain and update translations efficiently. Additionally, the lack of IntelliSense support hampers developers' productivity, leading to potential errors and inconsistencies in translations. Moreover, the module's limited capabilities for managing different languages result in cumbersome workflows and difficulties in maintaining language-specific content.

Another significant drawback is the cumbersome process of storing translations in separate JSON files, which can lead to cluttered project structures and version control issues. These challenges collectively contribute to a suboptimal translation experience, urging developers to seek alternative solutions for their localization needs.

Solution is simple; And no library is needed

In fact, doing a bullet proof translation mechanism for React and React Native projects does not need another library at all. In this tutorial we are going to solve this with a single hook:

  • Defining useS hook to use a string object.
  • Defining useLocale hook to keep locale settings, and also detect locale based on the user OS settings or browser settings.

What you need before

You can apply what you learn here to new projects, as well as your existing project

  • Install fireback v1.1.9 or later. You can find the binaries for different systems here: https://github.com/torabian/fireback/releases for installers binary, and you can place it inside your project folder and ignore it.

  • I use the VSCode, and "Run On Save extension" is enabled. You can run the translation from CLI as well, but having this extension makes life easier by far.

Step 1: Verify you have access to fireback

You need to make sure you have access to fireback binary, either installed globally, or you put it in the project directory, and ignored the file.

Fireback also could be installed on npm using `npm i -D fireback-tools'. Make sure you install it as dev dependency, so it's binaries do not bundle with react native apps.

Step 2: Create useLocale hook

export function useLocale() {
const [locale, setLocale] = useState({
lang: 'en',
region: 'us',
})

const dir = locale.lang === 'fa' || locale.lang === 'ar' ? 'rtl' : 'ltr'

// Here you can implement the rest of the necessary functionality
// for detecting the locale, or for example, extra function to set
// only the language or so.

return {lang, region, dir}
}

Step 3: Create the useS hook.

import { useLocale } from "./useLocale";

// This typescript generic is important, to use strongly typed translation
// keys
export function useS<T>(v: T): T {
/*
* This could be your own definition of the locale language
* This variable usually should include the current language in the app
* such as 'en', or 'fa', etc.
* you might also extend it to separate the language-locale such as en-us
* i haven't done yet due to no need
*/
const { lang } = useLocale();

/*
* Here we check if there lang is anything other than en, and in translation
* files we have such thing with a $ prefix - which auto generated by fireback
* we will access them instead. useS function will return always T,
* so all the translations will be typesafe anyway from typescript compiler
* perspective
*/
if (!lang || lang === "en") {
return v;
} else if (!v["$" + lang]) {
return v;
} else {
return v["$" + lang];
}
}

Step 4: Create 'strings' folder

How you organize the translations is up to you, in fact. I prefer to create a strings folder per module and place all of their translations into that directory. This way, when I move a module folder to another project or if I want to make it a library, I won't have to worry about the translations; they're already solved and attached to the component or module.

On the other hand, if you want to create a strings folder for the entire app, nothing would stop you.

Step 5: Create strings/strings-en.yml

It's critical to keep in mind that the Fireback Language Editor module assumes English as the primary language of the app. Simply put, English must be present, and other languages will be synced with keys from that one.

Now, let's put the content inside the YAML. All translation keys must go under the content key, otherwise they will not be considered translations.

If you are not familiar with YAML, think of it as JSON without quotes, and remember:

content:
loading: Loading...
done: Done :)

Is different from the code below. (Basically intention is super important)

content:
loading: Loading...
done: Done :)

So far, this was all the necessary steps we needed to take for translating our app.

Step 6: Use and config fireback language generator

Now we need to use the Fireback language generator to simplify key generation for us.

fireback gen strings --path ./src/strings/strings-en.yml --langs pl,fa

This command will generate two additional files in the same directory: strings-pl.yml and strings-fa.yml. If you open them, you will see identical content to your strings-en.yml.

Also in the same directory, you will find a translations.ts file. It contains content similar to the snippet below, which has generated TypeScript constants for all three languages and exported them as strings.

Step 7: Make this automated with VSCode run-on-save

Using the CLI each time for building the translations is cumbersome. Therefore, we utilize the "Run on save" extension in VSCode, which you can install.

Then, in our settings.json in VSCode, we need to add these rules. (If you've never modified this file, create a folder named .vscode at the root of your project and add settings.json inside it.)

{
// other configuration before

"emeraldwalk.runonsave": {
"commands": [
{
"match": "strings-([a-z][a-z]).yml$",
"cmd": "fireback gen strings --path ${file} --langs en,fa"
}
]
}

// other configuration after
}

It would basically detect any strings-xx.yml change in the project, and will run strings compiler for you.

Step 8: Use translations

At this stage, the tarnslation dictionary has been created fully, and we can use them by useS and access the keys on the s object. It's good to keep the names consistent across the entire project to make it clean.

React.js:

import { strings } from "./strings/translations";
export function MyComponent() {
const s = useS(strings)

return <p>{s.loading}</p>
}

React Native:

import { Text } from 'react-native';
import { strings } from "./strings/translations";
export function MyComponent() {
const s = useS(strings)

return <Text>{s.loading}</Text>
}

Conclusion

To summarize, we have just created a robust system for adding translations to our react or react native app. This method will help prevent many errors, such as missing keys in certain languages and hard-coded strings for translation.

The Fireback Strings CLI offers additional options that you may want to explore on your own. This feature is available starting from Fireback v1.1.9

Top reasons software teams and companies suffer from their own decisions

· 4 min read

When I join a company and I see managers complaining, coders complaining and designer complaining, I see a quite common pattern which I tried to not them happen in PixePlux projects and clients.

Use only MySQL or SQLite

Very often, people get into trouble by just using something weird, such as Postgres, Mongodb, Firebase, or 100 more database brands out there. In fact, MySQL or SQLite are capable of serving up to 99% of projects, up to facebook level data (MySQL). Spend a bit of time designing the right database, make two version of app which works both with SQLite and MySQL - using any orm this is just a config change - and never do not fall into hoax of some amazing database for a project which never gonna have more than 100 GB of database in decade.

They care about code more than product

We all read books about how to write "Clean code", so we did read "How to became milioner". The only important perspective of a software product is how users see that, not how or in which language it's written on.

Programmers usually do not care of software result, they are into topics which language it's used, which framework, which plugin, things which are only important to them, or maybe their tech leader.

Programmers should do their trial and error and lalaland task in codepen, github personal account, and do not bring any new library, code style, linting, plugin into the production. I see so often the entire project is stuck in how to use Redux clearly, and the project which code have 10 screens in 1 week, has gone nowhere in 3 months.

They produce large size or slow applications

Using wrong tools, you end up having software which consumes more resources than it should, this results in many issues.

  • They need very good computer to write code, run the project.
  • The application will end up large source and many users loose patience to download - specially if it's not so critical.
  • They can't ship easily, sign the app.

An example is projects written in Angular (Web) framework. The bundle size is that much big and rendering is so slow that every project feels so slow and laggy, not only it ends in user frustration, but also the developers themselves feel tired looking each time they want change something it takes couple of seconds and they want to start a new project.

There is no documentation or explanation of software

Many backends, front-ends, are being created without any explanation. Even a new developer in the same team needs to go few days into learning curve in order to run the project. Look at all major softwares, Windows, MySQL, Adobe, they all run without baby sitting from their vendors.

They are not using proper programming language

I did so much of research, and somehow ended up any project which lasted for decades, it's written in C/C++ it's no suprise, anything written in scripting languages, all the time needs maintaince and will not last 1-2 years even.

Due to my personal research these are the only proper tools:

  • Writting Android apps in Java (Not Hybrid, Ionic, Xamarin,...)
  • Writing Ios apps in ObjectiveC and Swift.
  • Writing any backend, system service, desktop application in C++, or in worst case Golang
  • React for frontend (Not Angular, Ember, Vuejs)

They are using things they do not need.

Docker, MariaDB, Fireback storage, Elasticbeans talk, CircleCi, Bitrise, Fastlane, and you name it. It seems to many people they cannot build anything without 80% of thirdparty services. Worlds most important software is written when none of these existed.

Using these tools, adds up a lot of extra time and overhead to deliver a project, which if it was written in C++ or Golang would end up 10% of the time.

Why to use lottie in React Native mobile development

· 3 min read

Animations are essential for most of user interfaces. Human being naturally are used to see things change in transition, a leaf is falling down with an speed. No one expecting to see the leaf on the tree, and immediately on the ground.

For the very same reason, we build applications in a way that actions are happening in an animation sequence. Creating animations in dedicated softwares are easy, for example in AfterEffects, you have a time line, keyframes and tons of visual tools to create all kind of custom animations you want, and exporting them as Gif or many different formats.

In programming, creating animation is difficult, most of the time you are not able to see how the animation works until you run it, and you need to work with scripts, and selecting elements then using JavaScript build those sequences, like:

Animated.sequence([
// decay, then spring to start and twirl
Animated.decay(position, {
// coast to a stop
velocity: { x: gestureState.vx, y: gestureState.vy }, // velocity from gesture release
deceleration: 0.997
}),
Animated.parallel([
// after decay, in parallel:
Animated.spring(position, {
toValue: { x: 0, y: 0 } // return to start
}),
Animated.timing(twirl, {
// and twirl
toValue: 360
})
])
]).start(); // start the sequence group

Animating using scripts like this might be only option for some actions, but it has drawbacks such as:

  • You are limited. It's only allowing some parameters of elements to be animated, such as transform, opacity
  • Only a programmer can adjust these. You loose all talent that UI/UX team has built in years.
  • It's not supporting advanced animations. If you want to create an envelop being closed after user clicking on "Send mail" button, it's gonna take hours and hours of work, if even possible after all.

Designing animations in AfterEffects

An alternative to all these problems is to design animations in an advanced tool such as AfterEffecs. Using plugin called lottie, you can export the 2d motion graphics into a json format, which later allows you to use it in Web, React Native or desktop applications

For example we created PixelPlux logo animated:


Or you can take a look at my design for Github logo:



Effects on the Mobile Project.

Using Lottie animations, specially well built ones, increases the user experience quality, for tasks such as processing a payment, searching for content, giving news bullitens and many more.

Zatrzymaj Chaos! Tłumaczenia Angular Wykonane Jak Trzeba Raz

· 6 min read
Ali Torabi

Krytyczne problemy z ng translate, i18n i innymi

Znaczenie tłumaczeń wydaje się być pomijane, a drugi język często traktowany jest po macoszemu w moich projektach; niektóre z nich nawet zaczynają się od niewłaściwych ciągów znaków w szablonach, aby później napotkać trudności przy próbie ich modyfikacji, ponieważ brak bezpieczeństwa typów uniemożliwia natychmiastowe wykrycie wszystkich wystąpień, co prowadzi do niejednolitego doświadczenia użytkownika, gdzie angielskie słowa mogą niespodziewanie pojawić się w hiszpańskim interfejsie, co negatywnie wpływa na reputację marki.

Moduł ng translate, choć początkowo wygodne narzędzie do obsługi tłumaczeń w aplikacjach Angular, często zawodzi w kilku kluczowych obszarach. Jednym z powszechnych problemów jest obecność statycznych ciągów znaków w szablonach, co sprawia, że utrzymanie i aktualizacja tłumaczeń staje się wyzwaniem. Dodatkowo, brak wsparcia IntelliSense ogranicza produktywność deweloperów, prowadząc do potencjalnych błędów i niekonsekwencji w tłumaczeniach. Ponadto, ograniczone możliwości modułu w zarządzaniu różnymi językami skutkują kłopotliwymi procesami i trudnościami w utrzymaniu treści związanych z językiem.

Innym istotnym problemem jest kłopotliwy proces przechowywania tłumaczeń w oddzielnych plikach JSON, co może prowadzić do zagraconych struktur projektu i problemów z kontrolą wersji. Te wyzwania wspólnie przyczyniają się do niedostatecznego doświadczenia związanego z tłumaczeniami, zmuszając deweloperów do poszukiwania alternatywnych rozwiązań dla swoich potrzeb lokalizacyjnych.

Rozwiązanie jest proste; I nie potrzeba biblioteki

W rzeczywistości, stworzenie niezawodnego mechanizmu tłumaczenia dla projektów Angular nie wymaga dodatkowej biblioteki. W tym samouczku rozwiążemy ten problem za pomocą dwóch elementów:

  • Komponentu podstawowego dla wszystkich komponentów w aplikacji
  • Usługi LocaleService, która będzie obsługiwać zmiany języka i publikować je wszędzie

Co potrzebujesz wcześniej

Możesz zastosować to, czego się nauczysz tutaj do nowych projektów, a także do istniejącego projektu

  • Aby nadążyć za szkoleniem, potrzebujesz pustego projektu angular 2+. Używam tutaj najnowszej wersji, która ma 'samodzielne' komponenty, ale jeśli korzystasz z starszej wersji Angular, nie będzie to miało znaczenia.

  • Zainstaluj fireback v1.1.9 lub nowszą wersję. Installers dla różnych systemów można znaleźć tutaj: https://github.com/torabian/fireback/releases

  • Korzystam z VSCode, a rozszerzenie Run On Save jest włączone. Możesz uruchamiać tłumaczenie również z wiersza poleceń, ale posiadanie tego rozszerzenia znacznie ułatwia życie.

Krok 1: Sprawdź, czy masz dostęp do fireback

Musisz upewnić się, że masz dostęp do binariów fireback, czy to zainstalowanych globalnie, czy też umieszczonych w katalogu projektu i zignorowanych.

Krok 2: Stwórz usługę LocaleService

Oto przekształcona wersja:

Usługa LocaleService jest prostą usługą, która będzie używana niemal wszędzie w projekcie, z jednym celem: przechowywać i synchronizować dane dotyczące lokalizacji.

W tej usłudze istnieje obserwowalna o nazwie locale$, którą będziemy subskrybować w komponencie, aby zmienić słownik zmiennych tłumaczeń. Dodatkowo, jest funkcja setLocale, która ustawia język. Na przykład, setLocale('en') zmieni język na angielski.

import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs';

@Injectable({
providedIn: 'root',
})
export class LocaleService {
private localeSubject = new BehaviorSubject<string>('en');
locale$ = this.localeSubject.asObservable();

constructor() {}

setLocale(locale: string) {
this.localeSubject.next(locale);
}
}

Krok 3: Stwórz komponent bazowy

Stworzenie komponentu bazowego to potężna funkcja Angulara i TypeScriptu, która ułatwia rozszerzanie niektórych podstawowych funkcji dla każdego komponentu w projekcie. Jeśli już masz taki komponent w projekcie, możesz zastosować tutaj kod do niego. Jeśli zaczynasz od nowa, utwórz nowy komponent o nazwie base.component.ts.

Ważne: Musisz użyć dekoratora @Directive zamiast @Component; w przeciwnym razie, Angular nie będzie go kompilować.

Po pierwsze, potrzebujemy zmiennej, na przykład s, aby przechowywać kluczowe tłumaczenia dla szablonu lub komponentu. Będzie ona chroniona, aby klasy rozszerzają

ce faktycznie miały do niej dostęp, jak również do pliku szablonu.

Następnie musimy wstrzyknąć LocaleService oraz obiekt kluczów tłumaczeń podczas konstrukcji. Ten obiekt będzie przechowywał tłumaczenia dla wszystkich języków (jak zobaczysz później, po wygenerowaniu pliku translations.ts). W konstruktorze będziemy wywoływać funkcję handleLocale, która jest po prostu subskrypcją do lokalizacji i zastąpi słownik zawartości s wybranym językiem.

Krok 4: Stwórz folder 'strings'

Jak zorganizujesz tłumaczenia, zależy od Ciebie. Ja preferuję tworzenie folderu strings dla każdego modułu i umieszczanie wszystkich ich tłumaczeń w tym katalogu. W ten sposób, gdy przeniosę folder modułu do innego projektu lub chcę go uczynić biblioteką, nie będę musiał martwić się o tłumaczenia; już są rozwiązane i dołączone do komponentu lub modułu.

Z drugiej strony, jeśli chcesz utworzyć folder strings dla całej aplikacji, nic Cię nie zatrzyma.

Krok 5: Stwórz plik strings/strings-en.yml

Krytyczne jest pamiętanie, że moduł Fireback Language Editor zakłada angielski jako główny język aplikacji. Innymi słowy, angielski musi być obecny, a inne języki będą synchronizowane z kluczami z tego.

Teraz umieśćmy treść wewnątrz YAML. Wszystkie klucze tłumaczeń muszą być umieszczone pod kluczem content, w przeciwnym razie nie zostaną one uznane za tłumaczenia.

Jeśli nie jesteś zaznajomiony z YAML, myśl o nim jak o JSON bez cudzysłowów, i pamiętaj:

content:
loading: Loading
done: Ready :)

Jest różny od kodu poniżej. (Podstawowa różnica to wcięcia).

content:
loading: Ładowanie...
done: Gotowe :)

Do tej pory to wszystkie niezbędne kroki, które musieliśmy podjąć, aby przetłumaczyć naszą aplikację.

Krok 6: Użyj i skonfiguruj generator języka fireback

Teraz musimy użyć generatora języka Fireback do uproszczenia generowania kluczy dla nas.

fireback gen strings --path ./src/app/components/loader-sample/strings/strings-en.yml --targets ts --langs pl,fa

To polecenie wygeneruje dwa dodatkowe pliki w tym samym katalogu: strings-pl.yml i strings-fa.yml. Jeśli je otworzysz, zobaczysz identyczną treść jak w twoim strings-en.yml.

Również w tym samym katalogu znajdziesz plik translations.ts. Zawiera on treść podobną do fragmentu poniżej, który wygenerował stałe TypeScript dla wszystkich trzech języków i wyeksportował je jako strings.

Krok 7: Zautomatyzuj to za pomocą VSCode run-on-save

Używanie CLI za każdym razem do budowania tłumaczeń jest kłopotliwe. Dlatego korzystamy z rozszerzenia "Run on save" w VSCode, które możesz zainstalować.

Następnie w pliku settings.json w VSCode musimy dodać te reguły. (Jeśli nigdy nie modyfikowałeś tego pliku, utwórz folder o nazwie .vscode w głównym katalogu twojego projektu i dodaj w nim plik settings.json.)

{
"emeraldwalk.runonsave": {
"commands": [
{
"match": "strings-([a-z][a-z]).yml$",
"cmd": "fireback gen strings --path ${file} --langs en,fa"
}
]
}
}

To w zasadzie wykryje każdą zmianę strings-xx.yml w projekcie i uruchomi dla ciebie kompilator ciągów.

Krok 8: Użyj tłumaczeń

W tej fazie, jesteśmy praktycznie gotowi do wykorzystania pliku tłumaczeń. W każdym komponencie, który rozszerza BaseComponent, będziesz mógł przekazać strings i uzyskać dostęp do zmiennej s zarówno wewnątrz komponentu, jak i w szablonie.

import { Component } from '@angular/core';
import { BaseComponent } from '../base.component';
import { LocaleService } from '../../locale.service';
import { strings } from './strings/translations';

@Component({
selector: 'app-loader-sample',
standalone: true,
imports: [],
templateUrl: './loader-sample.component.html',
styleUrl: './loader-sample.component.scss',
})
export class LoaderSampleComponent extends BaseComponent {
override s = strings;
constructor(private locale: LocaleService) {
super(locale, strings);
}
}

I możesz uzyskać dostęp do s i wszystkich kluczy bezpiecznie w szablonach HTML. Jak zauważyłeś, faktycznie nie musimy używać rurki do tłumaczeń w ogóle, co stanowi znaczącą korzyść zarówno pod względem wydajności, jak i czystości kodu.

<p>{{ s.loading }}</p>

Podsumowanie

Podsumowując, właśnie stworzyliśmy solidny system dodawania tłumaczeń do naszej aplikacji Angular. Ta metoda pomoże uniknąć wielu błędów, takich jak brakujące klucze w niektórych językach i twardo zakodowane ciągi dla tłumaczenia.