<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Claude Fassinou</title>
    <description>The latest articles on DEV Community by Claude Fassinou (@claudye).</description>
    <link>https://dev.to/claudye</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1071916%2Fec5f291c-7a1e-4a8a-a49b-e94f29624f78.png</url>
      <title>DEV Community: Claude Fassinou</title>
      <link>https://dev.to/claudye</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/claudye"/>
    <language>en</language>
    <item>
      <title>Creating an Api generator plugin for Claude Code</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Tue, 14 Oct 2025 07:41:35 +0000</pubDate>
      <link>https://dev.to/claudye/creating-an-api-generator-plugin-for-claude-code-256e</link>
      <guid>https://dev.to/claudye/creating-an-api-generator-plugin-for-claude-code-256e</guid>
      <description>&lt;p&gt;Claude Code plugins allow you to extend the capabilities of your AI assistant with custom commands, specialized agents, and tool integrations. In 3 minutes, create your first functional plugin. Read the full &lt;a href="https://docs.claude.com/en/docs/claude-code/plugins" rel="noopener noreferrer"&gt;Docs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why create plugins?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Intelligent Automation: Transform your repetitive workflows into reusable slash commands. A simple &lt;code&gt;/deploy prod&lt;/code&gt; can orchestrate tests, build, and deployment.&lt;br&gt;
Standardized Team Tooling: Share your best practices via automatically installed plugins. Your team uses the same code conventions, deployment scripts, and integrations.&lt;br&gt;
Limitless Extensibility: Connect Claude to your existing tools (databases, APIs, internal services) via MCP, create specialized agents for your business domains, and trigger automatic actions with hooks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Claude Code installed on your machine&lt;br&gt;
Basic command line knowledge&lt;br&gt;
Understanding the Plugin Architecture&lt;br&gt;
A Claude Code plugin follows a simple modular pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;api-generator-plugin/
├── .claude-plugin/
│   └── plugin.json          # Plugin metadata
├── commands/                 # Custom slash commands
├── agents/                   # Specialized agents (optional)
├── hooks/                    # Automations (optional)
└── .mcp.json                # External integrations (optional)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Creating an API Generator Plugin in 5 Steps&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will create a practical plugin that generates a complete REST API from a simple description.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Create the marketplace structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; ~/claude-marketplace/plugins
&lt;span class="nb"&gt;cd&lt;/span&gt; ~/claude-marketplace/plugins
&lt;span class="nb"&gt;mkdir &lt;/span&gt;api-generator-plugin
&lt;span class="nb"&gt;cd &lt;/span&gt;api-generator-plugin
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Create the plugin manifest&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;.claude-plugin/plugin.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"api-generator-plugin"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.0.0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Generates complete REST APIs with models, routes, and controllers"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Add the API generation command&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;commands/api-generate.md&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Generates&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;a&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;complete&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;REST&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;API&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;for&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;an&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;entity"&lt;/span&gt;
&lt;span class="na"&gt;args&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;entity&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Name&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;of&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;entity&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(ex.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;User,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Product,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Post)"&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;fields&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Comma-separated&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fields&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(ex.&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:string,email:string,age:number)"&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;framework&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Framework&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;to&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;use&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;(express,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;fastify,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;nestjs)"&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;express&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;

&lt;span class="gh"&gt;# API Generation for the {{entity}} Entity&lt;/span&gt;

I will create a complete REST API with the following components:

&lt;span class="gu"&gt;## 📁 Generated Structure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;src/&lt;br&gt;
├── models/{{entity}}.model.js&lt;br&gt;
├── controllers/{{entity}}.controller.js&lt;br&gt;
├── routes/{{entity}}.routes.js&lt;br&gt;
└── validators/{{entity}}.validator.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
## 📝 Detected Fields

{{fields}}

## 🔧 Generation Instructions

Create the following files, respecting {{framework}} conventions:

### 1. Data Model (`models/{{entity}}.model.js`)
- Define the schema with fields: {{fields}}
- Add timestamps (createdAt, updatedAt)
- Validate data types

### 2. Controller (`controllers/{{entity}}.controller.js`)
Implement these methods:
- `getAll{{entity}}s`: GET - Paginated list
- `get{{entity}}ById`: GET - Single item by ID
- `create{{entity}}`: POST - Create an item
- `update{{entity}}`: PUT - Update
- `delete{{entity}}`: DELETE - Delete

Handle errors with try/catch and return appropriate HTTP codes.

### 3. Routes (`routes/{{entity}}.routes.js`)
Create these endpoints:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;GET    /api/{{entity}}s&lt;br&gt;
GET    /api/{{entity}}s/:id&lt;br&gt;
POST   /api/{{entity}}s&lt;br&gt;
PUT    /api/{{entity}}s/:id&lt;br&gt;
DELETE /api/{{entity}}s/:id&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
### 4. Validators (`validators/{{entity}}.validator.js`)
Validate the fields: {{fields}}
- Correct data types
- Required fields
- Business constraints

## ✅ After Generation

1. Import the routes into `app.js`:
```

javascript
const {{entity}}Routes = require('./routes/{{entity}}.routes');
app.use('/api', {{entity}}Routes);


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;ol&gt;
&lt;li&gt; Test the endpoints with curl or Postman&lt;/li&gt;
&lt;li&gt; Document the API with Swagger (optional)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now generate the 4 complete files with production-ready code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Pattern&lt;/strong&gt;: This command uses complex templates with structured instructions to guide Claude in code generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Add a command for a unique endpoint&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create &lt;code&gt;commands/api-endpoint.md&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
`markdown
---
description: Adds a custom endpoint to an existing API
args:
  - name: entity
    description: Name of the entity concerned
    required: true
  - name: method
    description: HTTP Method (GET, POST, PUT, DELETE, PATCH)
    required: true
  - name: endpoint
    description: Endpoint path (ex. /search, /export)
    required: true
  - name: description
    description: Description of what the endpoint does
    required: true
---

# Adding a {{method}} {{endpoint}} endpoint for {{entity}}

## 📋 Specifications

**Entity**: {{entity}}
**Method**: {{method}}
**Endpoint**: `/api/{{entity}}s{{endpoint}}`
**Function**: {{description}}

## 🔧 Generation

Add this new endpoint to the existing file:

1. **Controller** (`controllers/{{entity}}.controller.js`):
   - Create the method that implements: {{description}}
   - Handle errors and validations
   - Return an appropriate JSON response

2. **Route** (`routes/{{entity}}.routes.js`):
   - Add: `router.{{method}}('{{endpoint}}', controller.methodName);`

3. **Suggested Tests**:
```bash
curl -X {{method}} http://localhost:3000/api/{{entity}}s{{endpoint}}
````

Generate the complete code for this endpoint.

**5. Configure the local marketplace**

At the root `~/claude-marketplace/`, create `marketplace.json`:

```json
{
  "name": "My Local Marketplace",
  "plugins": [
    {
      "source": "./plugins/api-generator-plugin"
    }
  ]
}
```

**6. Install and Test**

```bash
# Add your local marketplace
claude marketplace add file://~/claude-marketplace

# Install your plugin
claude marketplace install api-generator-plugin

# Test API generation
/api-generate User "name:string,email:string,age:number" express

# Add a search endpoint
/api-endpoint User GET /search "Search users by name or email"
```

Check your new commands with `/help`.

**Concrete Usage Example**

```bash
# Generate a complete API for a blog
/api-generate Post "title:string,content:text,authorId:number,published:boolean" express

# Add a publication endpoint
/api-endpoint Post PATCH /publish "Publish a blog post"

# Generate an e-commerce API
/api-generate Product "name:string,price:number,stock:number,category:string" fastify
```

**Design Concepts**

**Naming Convention**

  * Plugins: kebab-case (`api-generator-plugin`)
  * Commands: action verbs (`/api-generate`, `/api-endpoint`)
  * Variables: double curly braces (`{{entity}}`, `{{fields}}`)

**Structured Instruction Pattern**
Complex commands use markdown sections to guide Claude:

  * Clear instructions: Numbered steps
  * Code examples: Concrete snippets
  * Checklist: Post-generation actions

**Organization for Advanced Plugins**

```
advanced-api-plugin/
├── commands/
│   ├── generate/
│   │   ├── api-generate.md
│   │   └── api-crud.md
│   ├── enhance/
│   │   ├── api-auth.md
│   │   └── api-cache.md
│   └── deploy/
│       └── api-deploy.md
├── agents/
│   └── api-architect.json
└── hooks/
    └── hooks.json
```

**Advanced Components**

**Specialized Agents**

Create `agents/api-architect.json`:

```json
{
  "name": "api-architect",
  "instructions": "You are an expert API architect. You analyze needs, propose RESTful patterns, optimize performance, and ensure scalability. You are proficient in Express, Fastify, NestJS, and security best practices.",
  "model": "claude-sonnet-4-5"
}
```

Use the agent: `/agents` then select "api-architect"

**Automation Hooks**

Create `hooks/hooks.json`:

```json
{
  "pre-commit": "commands/api-lint.md",
  "post-generate": "commands/api-test-setup.md"
}
```

**MCP Integration (Databases)**

Create `.mcp.json` to connect your plugin to a database:

```json
{
  "mcpServers": {
    "database": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "DATABASE_URL": "postgresql://localhost/mydb"
      }
    }
  }
}
```

**Sharing and Deployment**

**For your Team**

Add to the repository's `.claude/settings.json`:

```json
{
  "marketplaces": [
    "file://./team-plugins"
  ],
  "plugins": [
    "api-generator-plugin"
  ]
}
```

Members automatically install the plugin by trusting the folder.

**Best Practices**

  * **Version**: Semantic versioning (1.0.0 → 1.1.0 → 2.0.0)
  * **Document**: `README.md` with usage examples
  * **Test**: Validate each command with real cases
  * **Iterate**: Add features progressively

**Quick Debugging**

Common Issues:

  * Plugin not recognized → Check that `commands/` is at the plugin root
  * Variables not replaced → Use `{{variable}}` with double curly braces
  * Command invisible → Validate the YAML frontmatter (3 dashes, correct syntax)
  * Installation errors → `claude marketplace validate file://~/claude-marketplace`

**Next Steps**

  * **Explore Marketplaces**: Get inspiration from community plugins
  * **Create Agents**: Specialize Claude for your domains (DevOps, Data, Security)
  * **Automate with Hooks**: Pre-commit checks, post-deploy notifications
  * **Integrate Your Tools**: Connect Jira, GitHub, Slack via MCP
  * **Share**: Contribute to the Claude Code ecosystem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>api</category>
      <category>tooling</category>
      <category>tutorial</category>
      <category>ai</category>
    </item>
    <item>
      <title>Laravel's `fillable property` and the Hidden Danger to Your Business App</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Fri, 26 Sep 2025 10:36:34 +0000</pubDate>
      <link>https://dev.to/claudye/laravels-fillable-property-and-the-hidden-danger-to-your-business-app-4pm8</link>
      <guid>https://dev.to/claudye/laravels-fillable-property-and-the-hidden-danger-to-your-business-app-4pm8</guid>
      <description>&lt;p&gt;Laravel is a powerful PHP framework, and its Eloquent ORM makes database interactions a breeze. However, a common pitfall involving the &lt;code&gt;$fillable&lt;/code&gt; property can lead to a critical security flaw known as a &lt;strong&gt;Mass Assignment Vulnerability&lt;/strong&gt;, potentially compromising your entire application.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Mass Assignment?
&lt;/h3&gt;

&lt;p&gt;Mass assignment is the practice of populating a model with an array of user input, usually from a form submission, in a single go. In Laravel, this often looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Populating a model with ALL request data&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 👈 DANGER ZONE!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is convenient, but it's dangerous if you don't control &lt;em&gt;which&lt;/em&gt; attributes are allowed to be set this way.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Role of &lt;code&gt;\$fillable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;$fillable&lt;/code&gt; property in a Laravel model is your &lt;strong&gt;white-list&lt;/strong&gt; for mass assignment. It specifies an array of columns that are &lt;strong&gt;safe&lt;/strong&gt; to be filled using methods like &lt;code&gt;create()&lt;/code&gt;, &lt;code&gt;update()&lt;/code&gt;, or &lt;code&gt;fill()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If an attribute is &lt;em&gt;not&lt;/em&gt; in the &lt;code&gt;$fillable&lt;/code&gt; array, Laravel's security layer will prevent it from being set via mass assignment.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Business Danger: Unrestricted Access
&lt;/h3&gt;

&lt;p&gt;This code illustrates the danger:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Vulnerable Model:&lt;/strong&gt; The &lt;code&gt;User&lt;/code&gt; model has a sensitive column, &lt;code&gt;is_admin&lt;/code&gt;, included in the &lt;code&gt;$fillable&lt;/code&gt; array.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In User.php&lt;/span&gt;
&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'is_admin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// 👈 THE FLAW&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Vulnerable Controller:&lt;/strong&gt; The application blindly accepts and assigns &lt;em&gt;all&lt;/em&gt; validated request data to the model.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// In TestController.php&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A malicious user can simply &lt;strong&gt;inject an &lt;code&gt;is_admin&lt;/code&gt; field&lt;/strong&gt; into their registration form data. Because the controller uses &lt;code&gt;create(\$request-&amp;gt;all())&lt;/code&gt; and &lt;code&gt;is_admin&lt;/code&gt; is in &lt;code&gt;$fillable&lt;/code&gt;, the application will happily set the user's &lt;code&gt;is_admin&lt;/code&gt; attribute to &lt;code&gt;true&lt;/code&gt; (or &lt;code&gt;1&lt;/code&gt;).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;🔥 The Result:&lt;/strong&gt; A standard user can instantly become an &lt;strong&gt;Administrator&lt;/strong&gt;, gaining unauthorized access to sensitive data, control panels, and potentially damaging your entire system and business integrity.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h3&gt;
  
  
  The Solution: Always Restrict &lt;code&gt;\$fillable&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;To protect your business, always adhere to this simple rule:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NEVER include sensitive, high-privilege columns like &lt;code&gt;is_admin&lt;/code&gt;, &lt;code&gt;role&lt;/code&gt;, &lt;code&gt;api_token&lt;/code&gt;, or &lt;code&gt;balance&lt;/code&gt; in your model's &lt;code&gt;\$fillable&lt;/code&gt; property.&lt;/strong&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;The Safe Code Fix:&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Remove the sensitive field from &lt;code&gt;$fillable&lt;/code&gt;:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The SECURE User.php&lt;/span&gt;
&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$fillable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'password'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="c1"&gt;// 'is_admin' is GONE! ✅&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Explicitly handle sensitive fields (if needed):&lt;/strong&gt; If you need to set &lt;code&gt;is_admin&lt;/code&gt; or another protected field, do it explicitly, line by line, &lt;strong&gt;only after checking authorization&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// The SECURE Controller code&lt;/span&gt;
&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$validatedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validate&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="nv"&gt;$validatedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="c1"&gt;// Set protected fields ONLY if an authorized admin is doing it.&lt;/span&gt;
&lt;span class="c1"&gt;// e.g., if (auth()-&amp;gt;user()-&amp;gt;isAdmin()) { \$user-&amp;gt;is_admin = 1; \$user-&amp;gt;save(); }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Protect your application by being meticulous with your &lt;code&gt;$fillable&lt;/code&gt; arrays!&lt;/p&gt;

&lt;p&gt;I am &lt;a href="https://github.com/Claudye" rel="noopener noreferrer"&gt;Claude Fassinou&lt;/a&gt;, Software developer, and Code reviewer.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>AI and the productivity trap</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Sat, 06 Sep 2025 07:49:21 +0000</pubDate>
      <link>https://dev.to/claudye/ai-and-the-productivity-trap-30p9</link>
      <guid>https://dev.to/claudye/ai-and-the-productivity-trap-30p9</guid>
      <description>&lt;h1&gt;
  
  
  AI and the productivity trap
&lt;/h1&gt;

&lt;p&gt;Honestly, we've all fallen for it. We're living in the age of AI, and the temptation to let it do the heavy lifting is huge. The problem is, if we don't master the basics anymore, we risk ending up with apps that look great on the surface but are riddled with hidden problems. Silent bugs, invisible technical debt... until the day everything collapses.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tech Lead's observation
&lt;/h2&gt;

&lt;p&gt;As a team lead, I see this every day. My developers are fully embracing tools like ChatGPT or Gemini, and I can't blame them—it's so much faster. But when I do a code review, I discover a bunch of stuff that has no business being there:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dead code hanging around for no good reason.&lt;/li&gt;
&lt;li&gt;Hardcoded values everywhere that should have been variables.&lt;/li&gt;
&lt;li&gt;Shaky or completely outdated logic.&lt;/li&gt;
&lt;li&gt;Old legacy code accidentally brought back to life.&lt;/li&gt;
&lt;li&gt;Features that mysteriously disappear between two versions.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The pace is insane, we're churning out projects, but no one is taking the time to actually read the code the AI generated. And that's where technical debt quietly piles up.&lt;/p&gt;

&lt;h2&gt;
  
  
  My strategy for regaining control
&lt;/h2&gt;

&lt;p&gt;I realized we had to take back the reins. Here's what's working for us:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend is sacred.&lt;/strong&gt; Backend code must be checked and re-checked—no exceptions. It's the foundation of everything.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We do TDD by hand.&lt;/strong&gt; We don't let the AI write our tests. We write our tests ourselves, and only then do we ask the AI to write the code. We meticulously review every unit test it proposes, because we can't blindly trust it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Smart prompts.&lt;/strong&gt; We force the AI to keep things simple. We ask it to apply the KISS (Keep It Simple, Stupid) and YAGNI (You Aren't Gonna Need It) principles. We don't want a massive, convoluted mess.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;We test seriously.&lt;/strong&gt; Every feature has to be tested from A to Z. The hidden bugs are the most insidious ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My pro tip: I turn my prompts into to-do lists. I ask the AI to validate each step, and I verify everything point by point. It sounds simple, but it massively reduces production errors.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;AI is a rocket ship, for sure, but it will never replace our critical eye and our expertise. It's up to us to learn to use it smartly, without getting lazy&lt;br&gt;
.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Fassinou Claude, Developer • Tech Lead • IT Project Manager in training&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>testing</category>
    </item>
    <item>
      <title>After and Before Hooks with Laravel Controller</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Fri, 20 Sep 2024 17:22:32 +0000</pubDate>
      <link>https://dev.to/claudye/after-and-before-hooks-with-laravel-controller-41o1</link>
      <guid>https://dev.to/claudye/after-and-before-hooks-with-laravel-controller-41o1</guid>
      <description>&lt;h3&gt;
  
  
  After and Before Hooks with Laravel Controller
&lt;/h3&gt;

&lt;p&gt;Have you ever encountered a situation where you want to perform an action before or after certain controller methods, perhaps to avoid code duplication, writing an event listener, or creating validation files? You want to keep things simple but move faster. Here's how you can solve this problem. Unfortunately, without an optimized approach, these repetitive tasks can lead to code duplication, making your application harder to maintain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you want to avoid duplicating code or repeatedly writing listeners? Are you looking for a simple and fast solution?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this article, we will solve this issue using a powerful and flexible approach: &lt;strong&gt;controller hooks in Laravel&lt;/strong&gt;. With this technique, you can automate cross-cutting actions without touching the code of your controller methods. It’s an elegant solution to improve the clarity and maintainability of your code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem: Code Duplication and Lack of Flexibility
&lt;/h2&gt;

&lt;p&gt;Let’s take a classic example. Suppose you have a controller with several methods that require similar operations, like initializing a service or formatting responses. The following code illustrates this repetition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExampleController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$someService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SomeService&lt;/span&gt; &lt;span class="nv"&gt;$someService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;someService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$someService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;methodA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;someService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;some_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Specific logic for methodA&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;formatResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;methodB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;someService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;some_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="c1"&gt;// Specific logic for methodB&lt;/span&gt;
        &lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="c1"&gt;// ...&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;formatResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;formatResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'success'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Problems&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Code duplication&lt;/strong&gt;: The service initialization is duplicated in each method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Clutter&lt;/strong&gt;: The response formatting is also duplicated, making long-term maintenance difficult.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lack of flexibility&lt;/strong&gt;: Adding new cross-cutting features, such as logging or error handling, requires modifying each method.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The Solution: Using Hooks in Controllers
&lt;/h2&gt;

&lt;p&gt;With &lt;strong&gt;controller hooks&lt;/strong&gt;, you can centralize these operations and apply them automatically before or after the execution of the relevant methods. Here’s how to refactor the previous example using this approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactoring with Hooks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;LaravelHooks\Traits\HasControllerHooks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExampleController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasControllerHooks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$someService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SomeService&lt;/span&gt; &lt;span class="nv"&gt;$someService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;someService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$someService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;methodA&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Specific logic for methodA&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;methodB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Specific logic for methodB&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;useHooks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;beforeCalling&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'methodA'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'methodB'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nv"&gt;$params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;someService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;some_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;withModel&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;afterCalling&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'methodA'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'methodB'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'success'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benefits of Using Hooks
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Cleaner and more concise code&lt;/strong&gt;: Each method focuses only on business logic. Repetitive actions are handled elsewhere.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized initialization&lt;/strong&gt;: No need to duplicate service initialization in every method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent response formatting&lt;/strong&gt;: Formatting is applied uniformly without duplication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Easier to add new features&lt;/strong&gt;: Hooks allow you to quickly add new functionalities like logging or error handling without modifying existing methods.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Practical Use Case: Payment Management
&lt;/h2&gt;

&lt;p&gt;Let’s take a concrete use case to illustrate this approach. Imagine a payment management system where you need to check security, initiate services, and format responses. Here’s how to use hooks to make the code cleaner and more maintainable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;LaravelHooks\Traits\HasControllerHooks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PaymentController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasControllerHooks&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$paymentService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;PaymentService&lt;/span&gt; &lt;span class="nv"&gt;$paymentService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$paymentService&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;createPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;verify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$paymentId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;verifyPayment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$paymentId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;checkStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Request&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$paymentId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;checkPaymentStatus&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$paymentId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;useHooks&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;beforeCalling&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'store'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'verify'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'checkStatus'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nv"&gt;$params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;paymentService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Payment operation initiated"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'method'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;currentMethod&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'user_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;id&lt;/span&gt;&lt;span class="p"&gt;()]);&lt;/span&gt;

            &lt;span class="c1"&gt;// Security check&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;securityService&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;verifyUserAllowed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;payment_id&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;UnauthorizedPaymentException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"User not authorized for this payment operation"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;afterCalling&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'store'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'verify'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'checkStatus'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'success'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'data'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addErrorHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;PaymentException&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;response&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'success'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'error'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;()],&lt;/span&gt; &lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Hooks Bring to the Table:
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Simplified service initialization&lt;/strong&gt;: No need to write initialization code in every method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automatic logging&lt;/strong&gt;: Each payment operation is logged without extra effort.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Centralized security checks&lt;/strong&gt;: Security is handled centrally before each payment-related method.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplified error handling&lt;/strong&gt;: A clear and centralized approach to handling specific exceptions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Source&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Claudye/laravel-hooks" rel="noopener noreferrer"&gt;laravel-hooks&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Unlock React Form Validation with Trivule: The Game-Changing Approach</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Tue, 28 May 2024 00:27:33 +0000</pubDate>
      <link>https://dev.to/claudye/simplify-react-form-validation-with-trivule-a-revolutionary-approach-28k8</link>
      <guid>https://dev.to/claudye/simplify-react-form-validation-with-trivule-a-revolutionary-approach-28k8</guid>
      <description>&lt;p&gt;If you love the simplicity of React, you'll adore &lt;a href="https://github.com/trivule/trivule"&gt;Trivule&lt;/a&gt;. This solution allows you to validate your forms easily and effectively. In this article, we will validate a form with two fields: email and message, to show how user-friendly and straightforward it is to use Trivule.&lt;/p&gt;

&lt;h2&gt;
  
  
  Example of output
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4ir8ynignoofq7s1isz.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq4ir8ynignoofq7s1isz.jpeg" alt="Image description" width="800" height="633"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/devalade/trivule-react"&gt;Extract from&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Creating the Project
&lt;/h2&gt;

&lt;p&gt;To start, create a project with Vite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm create vite@latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the instructions to complete the setup. I chose the TypeScript option, but you can choose whichever suits you best.&lt;/p&gt;

&lt;p&gt;Then, install Trivule:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;trivule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Validation Rules
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Email&lt;/strong&gt;: required, maximum 63 characters, must be a Gmail address.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message&lt;/strong&gt;: required, maximum 250 characters, must start with "Hello".&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating the React Component
&lt;/h2&gt;

&lt;p&gt;Create a file &lt;code&gt;form.tsx&lt;/code&gt; in your React working directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;SyntheticEvent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TrivuleForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;trivule&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Callback to define validation rules&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;bindRules&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TrivuleForm&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;make&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;required|email|endWith:@gmail.com|max:63&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;endWith&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Only Gmail addresses are allowed&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;required|startWith:Hello|max:250&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="c1"&gt;// React Component&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trivuleForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TrivuleForm&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;invalidClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;is-invalid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;afterBinding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;bindRules&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// The code runs once the form is found in the DOM&lt;/span&gt;
    &lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bind&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#myForm&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SyntheticEvent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;passes&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;preventDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"myForm"&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Trivule + React-vite&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form-group"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"form-group"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;textarea&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert alert-danger"&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"alert"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Integrating into the Application
&lt;/h3&gt;

&lt;p&gt;Import and use the &lt;code&gt;Form&lt;/code&gt; component in &lt;code&gt;App.tsx&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./App.css&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Form&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./form&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;App&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Form&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Styling Flexibility
&lt;/h2&gt;

&lt;p&gt;Trivule is agnostic about the styling of your form. It provides an API that allows you to apply your own styles based on the validation status. You can define classes to indicate valid or invalid states, and Trivule will handle the rest.&lt;/p&gt;

&lt;h3&gt;
  
  
  Learn More
&lt;/h3&gt;

&lt;p&gt;To further your knowledge of Trivule, check out the following resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.trivule.com/docs/tuto"&gt;Quick start tutorial | Trivule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.trivule.com/docs/rules"&gt;Validation Rules&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.trivule.com/docs/messages"&gt;Messages | Trivule&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.trivule.com/docs/events"&gt;Events | Trivule&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also create a TrivuleForm component, export it, and validate your forms without manual initialization. Check out an example on &lt;a href="https://github.com/devalade/trivule-react"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Easily Understanding Lifecycles in Programming</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Mon, 27 May 2024 10:37:20 +0000</pubDate>
      <link>https://dev.to/claudye/easily-understanding-lifecycles-in-programming-3k6m</link>
      <guid>https://dev.to/claudye/easily-understanding-lifecycles-in-programming-3k6m</guid>
      <description>&lt;p&gt;In the world of programming, every application follows a specific journey from its creation to its closure. This journey, often termed as a "lifecycle," is fundamental for developers. But what does this really mean? Let me explain to you in a simple and concrete manner.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;What is a Lifecycle?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Imagine your application as a living organism that traverses different phases of its life, from birth to death. Each phase or lifecycle represents a crucial moment in the operation of your application. These moments are triggered by events like the application's launch, user interaction, or its closure.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Why Do We Use Lifecycles?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Lifecycles are used to manage the behavior of the application at various points during its execution. They allow developers to take specific actions at each step, such as initializing variables, loading data, or cleaning up resources. In summary, lifecycles provide a structure for organizing code and ensuring that the application functions correctly in all situations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Illustration&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Imagine you're building a house. You have key stages like the foundation, walls, roof, etc. Each stage requires specific actions to progress to the next. Lifecycles work similarly for an application, ensuring that each phase of its execution is properly managed.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;What Problems Do Lifecycles Solve?&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Without lifecycles, managing the different situations an application may encounter would be complicated. For example, what happens when the user closes the application or interacts with a form? Lifecycles offer entry points to execute the necessary code for each event, effectively addressing these questions.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Some Frameworks That Use Lifecycles&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Many modern frameworks simplify the development process by using lifecycles. Whether it's a frontend or backend framework, the operating principle is almost the same. But let's focus on frontend frameworks.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Practical Examples of Lifecycles&lt;/strong&gt;
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;During Application Creation&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt;: Use the &lt;code&gt;useState&lt;/code&gt; hook to prepare initial variables.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Angular&lt;/strong&gt;: Angular uses the constructor to define initial variables, then &lt;code&gt;ngOnInit&lt;/code&gt; to prepare variables, for example, during component initialization.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;initialValue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Load data from a server&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;After Application Creation: Initializing Interactions&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt;: Use &lt;code&gt;useEffect&lt;/code&gt; to inject variables and initialize interactions after component rendering.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Initialize interactions&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Angular&lt;/strong&gt;: Use &lt;code&gt;ngAfterViewInit&lt;/code&gt; to manipulate DOM elements after HTML content is ready.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="nf"&gt;ngAfterViewInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Manipulate DOM elements&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;When Content Changes&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;React&lt;/strong&gt;: &lt;code&gt;useEffect&lt;/code&gt; can be used with a dependency to react to content changes.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;    &lt;span class="nf"&gt;useEffect&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// React to content changes&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Angular&lt;/strong&gt;: &lt;code&gt;ngOnChanges&lt;/code&gt; can be used to handle changes in component-bound properties.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;    &lt;span class="nf"&gt;ngOnChanges&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;SimpleChanges&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;changes&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// React to content changes&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's important to consult the documentation of these frameworks to better understand how to use them.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Lifecycles are an essential tool for every developer, allowing for effective management of an application's lifecycle and ensuring a consistent user experience. By understanding and applying these fundamental concepts, developers can build robust and reliable applications, ready to tackle the challenges of the ever-evolving digital world.&lt;/p&gt;

&lt;p&gt;With lifecycles, you can transform a simple application into an exceptional user experience, managing each stage in a structured and efficient manner. Embark on this journey and discover how lifecycles can revolutionize your approach to application development.&lt;/p&gt;

&lt;p&gt;In the next article, we'll explore how to use lifecycles according to developers' needs in three major frameworks. Subscribe to stay updated!&lt;/p&gt;

&lt;p&gt;Follow me on:&lt;br&gt;&lt;br&gt;
&lt;a href="https://dev.to/claudye"&gt;Dev.to&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://github.com/Claudye"&gt;Github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>angular</category>
      <category>frontend</category>
      <category>backend</category>
    </item>
    <item>
      <title>Unlock Angular Form Validation Magic with Trivule: The Game-Changing Approach</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Tue, 07 May 2024 10:06:42 +0000</pubDate>
      <link>https://dev.to/claudye/unlock-angular-form-validation-magic-with-trivule-the-game-changing-approach-1d5n</link>
      <guid>https://dev.to/claudye/unlock-angular-form-validation-magic-with-trivule-the-game-changing-approach-1d5n</guid>
      <description>&lt;p&gt;If you're aiming to save time, minimize effort, yet achieve sophisticated form validation in your Angular projects, this article is for you. Form validation in Angular can sometimes be complex, especially when managing error messages, dealing with multiple if-else conditions, handling button states, and styling invalid inputs. But fear not! With this method, you won't need to write any conditions at all. Yes, you read that right. Just a simple configuration, and you're good to go.&lt;/p&gt;

&lt;p&gt;To achieve this, I'll introduce you to a well-thought-out library designed to streamline form handling, saving you time and effort: &lt;a href="https://github.com/trivule"&gt;Trivule&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Install Trivule in Your Angular Projects&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;trivule
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Create Your Angular Component&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng g c contact-form
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;Navigate to Your Component TypeScript and HTML Files&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;HTML Template&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;#signupForm&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;Validation scenario with Trivule&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;fieldset&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;
            File
            &lt;span class="c"&gt;&amp;lt;!--Required file, with mimes type .png--&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt; &lt;span class="na"&gt;data-tr-rules=&lt;/span&gt;&lt;span class="s"&gt;"required|mimes:.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback=&lt;/span&gt;&lt;span class="s"&gt;"file"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;
            Email
            &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;data-tr-rules=&lt;/span&gt;&lt;span class="s"&gt;"required|email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;label&amp;gt;&lt;/span&gt;Your favorite language&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;select&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"favorite_cuisine"&lt;/span&gt; &lt;span class="na"&gt;data-tr-rules=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&lt;/span&gt; &lt;span class="na"&gt;selected&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Select ...&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;JavaScript&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;TypeScript&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
            &lt;span class="nt"&gt;&amp;lt;option&amp;gt;&lt;/span&gt;HMTL&lt;span class="nt"&gt;&amp;lt;/option&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/select&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback=&lt;/span&gt;&lt;span class="s"&gt;"favorite_cuisine"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/fieldset&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"Subscribe"&lt;/span&gt; &lt;span class="na"&gt;data-tr-submit&lt;/span&gt; &lt;span class="na"&gt;(click)=&lt;/span&gt;&lt;span class="s"&gt;"save()"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;Component TypeScript&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ViewChild&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/core&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;TrivuleForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;trivule&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;standalone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;RouterOutlet&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrl&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;AfterViewInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ViewChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;signupForm&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;signupForm&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HTMLElement&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nl"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;TrivuleForm&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nf"&gt;ngAfterViewInit&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signupForm&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TrivuleForm&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;signupForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;validClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is-valid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="c1"&gt;//class to add when the valid passes&lt;/span&gt;
        &lt;span class="na"&gt;invalidClass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;is-invalid&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="c1"&gt;//class to add when the valid fails&lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formIsValid&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;passes&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// indicate if the validation passes&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;validatedInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Get only validated input&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;inputs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Get all inputs&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;failedInputs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;trivuleForm&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;failed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//Get failed inputs&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key Points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;@ViewChild('signupForm') signupForm!: ElementRef&amp;lt;HTMLElement&amp;gt;;&lt;/code&gt; selects the form or HTML element containing the inputs, in our case, the HTML element with the &lt;code&gt;#signupForm&lt;/code&gt; attribute.&lt;/li&gt;
&lt;li&gt;  In the &lt;code&gt;ngAfterViewInit&lt;/code&gt; method, we initialize a Trivule instance, passing it the HTML element. Then, the &lt;code&gt;init&lt;/code&gt; method on &lt;code&gt;trivuleForm&lt;/code&gt; proceeds with the validation as the user interacts with the form.&lt;/li&gt;
&lt;li&gt;  Attributes prefixed with &lt;code&gt;data-tr&lt;/code&gt; are Trivule attributes that instruct the input on how to behave, where to display messages, and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Attribute Explanation:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;code&gt;data-tr-rules&lt;/code&gt;: Specifies validation rules.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;data-tr-feedback&lt;/code&gt;: Indicates where an HTML element will display feedback.&lt;/li&gt;
&lt;li&gt;  &lt;code&gt;data-tr-submit&lt;/code&gt;: Enables or disables the button based on form validity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://www.trivule.com"&gt;Learn More about Trivule&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/trivule"&gt;Trivule on Github&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Trivule can also be used to manage Reactive Forms in Angular.&lt;br&gt;
If you found this article helpful, share it and subscribe to my account for more insightful content.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to add or modify a validation rule in Trivule?</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Thu, 02 May 2024 10:33:17 +0000</pubDate>
      <link>https://dev.to/claudye/how-to-add-or-modify-a-validation-rule-in-trivule-324b</link>
      <guid>https://dev.to/claudye/how-to-add-or-modify-a-validation-rule-in-trivule-324b</guid>
      <description>&lt;p&gt;In &lt;a href="https://www.trivule.com"&gt;Trivule&lt;/a&gt;, rules govern how form fields are validated. You might find that the existing rules don't quite fit your needs or that you need to introduce custom rules. Here's a quick guide on how to add or modify rules in &lt;a href="https://www.trivule.com"&gt;Trivule&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1: Accessing the &lt;code&gt;rule&lt;/code&gt; Method
&lt;/h4&gt;

&lt;p&gt;To add or modify a rule, you'll use the &lt;code&gt;rule&lt;/code&gt; method of the &lt;code&gt;TrBag&lt;/code&gt; class. This method allows you to define the behavior of a rule according to your requirements.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 2: Writing the Rule Callback
&lt;/h4&gt;

&lt;p&gt;The heart of defining a rule lies in the rule callback function. This function takes in the value of the field to be validated and returns an object indicating whether the validation passes or fails. You can customize the validation logic within this callback.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 3: Defining the Rule Parameters
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notSudoRule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;passes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sudo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Optional&lt;/span&gt;
    &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Optional&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When defining a rule, you'll provide several parameters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rule Name&lt;/strong&gt;: Assign a name to your rule.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Callback Function&lt;/strong&gt;: Define the callback function that implements the validation logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Message&lt;/strong&gt;: Optionally, provide a message to be displayed when the rule fails.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Locale&lt;/strong&gt;: If needed, specify the language for error messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Step 4: Example Usage
&lt;/h4&gt;

&lt;p&gt;Let's consider an example where we want to create a rule called &lt;code&gt;notSudo&lt;/code&gt;, which ensures that the input value is not equal to "sudo". We define the rule callback function accordingly and use the &lt;code&gt;TrBag.rule&lt;/code&gt; method to add the rule to Trivule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;notSudoRule&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;param&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;passes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sudo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;text&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Optional&lt;/span&gt;
    &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Optional&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="nx"&gt;TrBag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;notSudo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;notSudoRule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The input value should not be 'sudo'&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Step 5: Testing Your Rule
&lt;/h4&gt;

&lt;p&gt;Once you've added your custom rule, you can immediately start using it in your forms. Test the rule to ensure it behaves as expected and meets your validation requirements.&lt;/p&gt;

&lt;h4&gt;
  
  
  Conclusion
&lt;/h4&gt;

&lt;p&gt;By following these steps, you can easily add or modify rules in &lt;a href="https://www.trivule.com"&gt;Trivule&lt;/a&gt; to tailor form validation to your specific needs. Experiment with different validation logic and parameters to create robust and effective validation rules for your applications.&lt;/p&gt;

&lt;p&gt;That's it! You've successfully learned how to add or modify rules in &lt;a href="https://www.trivule.com"&gt;Trivule&lt;/a&gt;. Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How be notified by e-mail when a critical error occurs in a Laravel application?</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Thu, 25 Apr 2024 10:13:50 +0000</pubDate>
      <link>https://dev.to/claudye/how-can-i-be-notified-by-e-mail-when-a-critical-error-occurs-in-a-laravel-application-e4</link>
      <guid>https://dev.to/claudye/how-can-i-be-notified-by-e-mail-when-a-critical-error-occurs-in-a-laravel-application-e4</guid>
      <description>&lt;p&gt;Although Laravel manages logs efficiently, it can sometimes be crucial to keep a close eye on errors during the development of certain projects. This tip will enable you to receive an e-mail as soon as a critical error occurs on your server. It is important to note that it is recommended to send only critical errors to avoid saturating your inbox.&lt;br&gt;
The simplest approach (in my opinion) is to use bug-tracking software such as Sentry (or equivalent); this will help regulate notifications. But what if I don't want these services? I can do my own thing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Creation of the &lt;code&gt;ExceptionMail&lt;/code&gt; mail class
&lt;/h2&gt;

&lt;p&gt;Run this command in your Laravel project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan make:mail ExceptionMail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the mail class is created, we'll modify it. Instead of creating a separate view, I'll inject HTML content directly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Mail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Bus\Queueable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Mail\Mailable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Mail\Mailables\Content&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Mail\Mailables\Envelope&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Queue\SerializesModels&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExceptionMail&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Mailable&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Queueable&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;SerializesModels&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$htmlString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;//&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;envelope&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Envelope&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Envelope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;subject&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'A critical error occurred'&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;Content&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;htmlString&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;htmlString&lt;/span&gt;
        &lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Sending the Email
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;app/Exceptions/Handler.php&lt;/code&gt; class, you'll find Laravel's base exception handling class. Let's add a private &lt;code&gt;sendMail&lt;/code&gt; method to this class and called it in the &lt;code&gt;rergister&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Exceptions&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Mail\ExceptionMail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Foundation\Exceptions\Handler&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;ExceptionHandler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Mail&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Throwable&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Handler&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;ExceptionHandler&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;register&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;reportable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;sendMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Throwable&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;App&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;isLocal&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;//Developer emails&lt;/span&gt;
        &lt;span class="nv"&gt;$emails&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"developers@email.coms"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"etc@etc.com"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

        &lt;span class="nv"&gt;$htmlStr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"An error occurred while processing the request. Here is the error"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;//You should normally return the file, the line, the code and the message, so that you have an idea of what it's about without consulting the log&lt;/span&gt;
        &lt;span class="nv"&gt;$htmlStr&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getMessage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;Mail&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$emails&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ExceptionMail&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$htmlStr&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;\Throwable&lt;/span&gt; &lt;span class="nv"&gt;$th&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;//Your code&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I used Laravel 9; please adapt according to your version.&lt;/li&gt;
&lt;li&gt;Ensure not to send all exceptions, but only critical errors.&lt;/li&gt;
&lt;li&gt;It's not advisable to send email notifications in production mode.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to simplify form validation in your Laravel projects and save time, I recommend trying out this library &lt;a href="https://github.com/trivule/trivule"&gt;Trivule&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://twitter.com/devclaudy"&gt;Twitter&lt;/a&gt; and &lt;a href="https://dev.to/claudye"&gt;Dev Community&lt;/a&gt; for more tips and shares.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Best and Simple Real-Time Validation Library Without Needing JavaScript Code</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Tue, 23 Apr 2024 18:31:15 +0000</pubDate>
      <link>https://dev.to/claudye/best-and-simple-real-time-validation-library-without-needing-javascript-code-5bjm</link>
      <guid>https://dev.to/claudye/best-and-simple-real-time-validation-library-without-needing-javascript-code-5bjm</guid>
      <description>&lt;p&gt;&lt;strong&gt;Expected results&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3g1kd3ozhbl8b67cjdk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe3g1kd3ozhbl8b67cjdk.png" alt="Image description" width="412" height="142"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Validating a form in HTML and CSS can be challenging, but it becomes easier with Trivule. Learn by example how to use dynamic validation rules such as &lt;code&gt;dateBefore&lt;/code&gt;, &lt;code&gt;dateAfter&lt;/code&gt;, and &lt;code&gt;dateBetween&lt;/code&gt; (alias &lt;code&gt;between&lt;/code&gt;) to make date validation interactive and real-time. Learn more in this &lt;a href="https://dev.to/claudye/discover-a-powerful-form-validation-library-without-the-need-for-javascript-code-3b2g"&gt;article&lt;/a&gt; or in the &lt;a href="https://www.trivule.com/docs"&gt;documentation&lt;/a&gt; of &lt;a href="https://www.trivule.com"&gt;Trivule&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: HTML Element Configuration
&lt;/h3&gt;

&lt;p&gt;Start by integrating a date field into your HTML form. Add the &lt;code&gt;data-tr-rules&lt;/code&gt; and &lt;code&gt;data-tr-messages&lt;/code&gt; attributes to define validation rules and custom error messages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your date of birth&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt;
    &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"date"&lt;/span&gt;
    &lt;span class="na"&gt;data-tr-rules=&lt;/span&gt;&lt;span class="s"&gt;"required|dateBetween:1990-01-01 00:00,1999-12-31 23:00"&lt;/span&gt;
    &lt;span class="na"&gt;data-tr-messages=&lt;/span&gt;&lt;span class="s"&gt;"Date of birth is required|You must be born between 1990 and 1999."&lt;/span&gt;
    &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"birthDay"&lt;/span&gt;
  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- Location to display error messages, can be any HTML element --&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback=&lt;/span&gt;&lt;span class="s"&gt;"birthDay"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Including the Trivule Library
&lt;/h3&gt;

&lt;p&gt;Add the Trivule script to your HTML page to enable form validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://www.trivule.com/js/trivule.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Trivule Initialization
&lt;/h3&gt;

&lt;p&gt;Create an instance of &lt;code&gt;TrivuleInput&lt;/code&gt; by specifying the selector of the element to validate (here, a date field) and call the &lt;code&gt;init()&lt;/code&gt; method to activate validation.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;trInput&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;TrivuleInput&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;input[name=birthDay]&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;trInput&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Some Validation Rules on Dates
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;dateBefore:date&lt;/code&gt;&lt;/strong&gt;: Validates that the date is before the specified date.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;dateAfter:date&lt;/code&gt;&lt;/strong&gt;: Validates that the date is after the specified date.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;dateBetween:start,end&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;date|between:start,end&lt;/code&gt;&lt;/strong&gt;: Validates that the date is between the two specified dates, inclusively.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: The &lt;code&gt;between&lt;/code&gt; rule must be preceded by the &lt;code&gt;date&lt;/code&gt; rule so that the &lt;code&gt;between&lt;/code&gt; rule knows it will compare dates.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Date validation with Trivule offers a simple yet powerful solution to ensure users input valid dates in your forms. By using rules like &lt;code&gt;dateBefore&lt;/code&gt;, &lt;code&gt;dateAfter&lt;/code&gt;, and &lt;code&gt;dateBetween&lt;/code&gt;, easily customize the validation behavior according to your specific needs. There are several other rules in Trivule; please consult them &lt;a href="https://www.trivule.com/docs/rules"&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Discover a Powerful Form Validation Library Without the Need for JavaScript Code</title>
      <dc:creator>Claude Fassinou</dc:creator>
      <pubDate>Sat, 20 Apr 2024 13:44:26 +0000</pubDate>
      <link>https://dev.to/claudye/discover-a-powerful-form-validation-library-without-the-need-for-javascript-code-3b2g</link>
      <guid>https://dev.to/claudye/discover-a-powerful-form-validation-library-without-the-need-for-javascript-code-3b2g</guid>
      <description>&lt;p&gt;Dive into the world of HTML validation with Trivule: a revolutionary library that automates and streamlines form validation without the need for JavaScript. Free yourself from the hassles of validation and focus on the core of your application, saving valuable time with every interaction with your forms.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Simple Installation:&lt;/strong&gt; Get started in a flash with easy installation and initialization.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Trivule&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="nx"&gt;tr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;init&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Code-Free Simplicity:&lt;/strong&gt; Apply complex validation rules without ever touching a line of JavaScript. Trivule handles validation rules with ease.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;data-tr-rules=&lt;/span&gt;&lt;span class="s"&gt;"required|email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Validation Trigger:&lt;/strong&gt; Trigger validation in real-time using a range of built-in or custom JavaScript events.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;data-tr-events=&lt;/span&gt;&lt;span class="s"&gt;"mouseenter|blur|my-custom-event"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Easy Customization:&lt;/strong&gt; Style your form fields based on their validation status using CSS classes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;data-tr-invalid-class=&lt;/span&gt;&lt;span class="s"&gt;"invalid"&lt;/span&gt; &lt;span class="na"&gt;data-tr-valid-class=&lt;/span&gt;&lt;span class="s"&gt;"valid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Customized Messages:&lt;/strong&gt; Enhance user experience by displaying tailored validation messages.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;data-tr-rules=&lt;/span&gt;&lt;span class="s"&gt;"required"&lt;/span&gt; &lt;span class="na"&gt;data-tr-messages=&lt;/span&gt;&lt;span class="s"&gt;"This field is required."&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Message Display Control:&lt;/strong&gt; Specify where to display error messages for a field in case of validation failure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;  &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;data-tr-feedback=&lt;/span&gt;&lt;span class="s"&gt;"input-name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Total Control:&lt;/strong&gt; Master the behavior of your forms with advanced JavaScript functionalities.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Advanced Customization:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Explore a range of advanced features to meet your specific needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Actions:&lt;/strong&gt; Define actions to take based on the validation state of a field.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;JavaScript Configuration:&lt;/strong&gt; Interact with your forms autonomously and powerfully.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Custom Extensions:&lt;/strong&gt; Add new validation rules for a tailored experience.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Multilingual Support:&lt;/strong&gt; Personalize validation messages in multiple languages for a global reach.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In summary, Trivule offers a wide range of intuitive attributes to configure and validate your forms effortlessly. Its simple installation and power make it the perfect tool to ensure the quality of your user data. Dive into the world of HTML validation with Trivule today and transform your web development experience.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.trivule.com"&gt;Discover Trivule here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
    </item>
  </channel>
</rss>
