<?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: Samuel S</title>
    <description>The latest articles on DEV Community by Samuel S (@samseptiano).</description>
    <link>https://dev.to/samseptiano</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%2F1026397%2F199a4d99-56b1-4125-989e-916aa076d6ea.jpg</url>
      <title>DEV Community: Samuel S</title>
      <link>https://dev.to/samseptiano</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samseptiano"/>
    <language>en</language>
    <item>
      <title>Create your own genAI apps fast using PartyRock</title>
      <dc:creator>Samuel S</dc:creator>
      <pubDate>Fri, 23 May 2025 08:31:48 +0000</pubDate>
      <link>https://dev.to/samseptiano/create-your-own-genai-apps-fast-using-partyrock-kgn</link>
      <guid>https://dev.to/samseptiano/create-your-own-genai-apps-fast-using-partyrock-kgn</guid>
      <description>&lt;p&gt;Hello everyone! Today I want to talk about &lt;strong&gt;Generative AI (GenAI)&lt;/strong&gt;. The development of GenAI is growing rapidly and becoming more mature. We’re all familiar with prompting-based GenAI apps like ChatGPT by OpenAI and Gemini by Google.&lt;/p&gt;

&lt;p&gt;But…&lt;br&gt;
Have you ever thought about creating a GenAI-based app that's simple, fast, and easy to build—without worrying about backend code, AI models, or heavy cloud costs?&lt;/p&gt;

&lt;p&gt;Well, PartyRock by AWS might be just the solution you're looking for!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vyji983q25o2imp5ecs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7vyji983q25o2imp5ecs.png" alt="sample-dashboard-partyrock" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is PartyRock?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;PartyRock&lt;/strong&gt; is an AI app builder from &lt;strong&gt;Amazon Web Services (AWS)&lt;/strong&gt; that allows anyone—even those with no coding background—to create AI-powered applications in just minutes.&lt;/p&gt;

&lt;p&gt;You simply drag and drop components, add your prompts, and... voilà! You’ve built an app that can generate text, answer questions, or even write poems.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why is PartyRock Exciting?&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No Coding Needed
Perfect for everyone—whether you're a developer or just GenAI-curious.&lt;/li&gt;
&lt;li&gt;Prompt-Based&lt;/li&gt;
&lt;li&gt;You design how your app works with text-based instructions—just like using ChatGPT, but in a more interactive format.&lt;/li&gt;
&lt;li&gt;Fast to Build, Easy to Share
Once your app is ready, it’s instantly accessible via a web link. Share it with anyone, anytime.&lt;/li&gt;
&lt;li&gt;Powered by AWS Bedrock
Under the hood, PartyRock leverages advanced GenAI models like Claude, Titan, or Meta’s LLaMa via AWS Bedrock—so it's powerful and responsive.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Examples of Apps You Can Build&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A Simple AI Translator&lt;/li&gt;
&lt;li&gt;Instagram Caption Generator&lt;/li&gt;
&lt;li&gt;Resume Assistant&lt;/li&gt;
&lt;li&gt;YouTube Content Idea Generator&lt;/li&gt;
&lt;li&gt;Product Review Sentiment Analyzer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this can be built just by entering prompts and designing the UI. No server deployments, no API key headaches—not even JSON required!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Can It Be Integrated into Other Apps?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Absolutely.&lt;br&gt;
If you're an Android developer, you can embed your PartyRock app in a WebView.&lt;br&gt;
If you need an API version, you can prototype your idea with PartyRock and later build a more advanced version using AWS Bedrock APIs.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Sounds fun? ready to try?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Try it for yourself at &lt;a href="https://partyrock.aws" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>genai</category>
      <category>ai</category>
      <category>aws</category>
      <category>nocode</category>
    </item>
    <item>
      <title>Fake news detection with Keras and Python</title>
      <dc:creator>Samuel S</dc:creator>
      <pubDate>Fri, 23 May 2025 07:56:55 +0000</pubDate>
      <link>https://dev.to/samseptiano/fake-news-detection-with-keras-and-python-3jej</link>
      <guid>https://dev.to/samseptiano/fake-news-detection-with-keras-and-python-3jej</guid>
      <description>&lt;p&gt;In the digital age, where information spreads faster than ever, fake news has become a real threat. Whether it's misleading headlines or entirely fabricated stories, false information can influence public opinion, sway elections, or even endanger lives. To combat this, I built a sample of machine learning-based fake news detection model using &lt;strong&gt;TensorFlow&lt;/strong&gt; and &lt;strong&gt;Natural Language Processing (NLP)&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This project demonstrates a practical implementation of Fake News Detection using TensorFlow, leveraging &lt;strong&gt;Natural Language Processing (NLP)&lt;/strong&gt; techniques and deep learning. The model is trained to classify whether a given news article is real or fake, which is a crucial task in today's information-driven society.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technologies Used
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TensorFlow 2.x – for building and training the neural network&lt;/li&gt;
&lt;li&gt;Keras – high-level API for defining the model&lt;/li&gt;
&lt;li&gt;Natural Language Processing (NLP) – tokenization, stopword removal, vectorization&lt;/li&gt;
&lt;li&gt;Scikit-learn – for preprocessing, splitting datasets, and evaluating model accuracy&lt;/li&gt;
&lt;li&gt;Pandas &amp;amp; NumPy – for data manipulation&lt;/li&gt;
&lt;li&gt;Matplotlib – for result visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Binary classification: Fake (1) vs. Real (0)&lt;/li&gt;
&lt;li&gt;Dataset preprocessing: stopwords, stemming, tokenization&lt;/li&gt;
&lt;li&gt;Deep learning model using LSTM layers&lt;/li&gt;
&lt;li&gt;Training and validation performance tracking&lt;/li&gt;
&lt;li&gt;Organized Jupyter notebook for easy understanding&lt;/li&gt;
&lt;li&gt;Model evaluation with confusion matrix, accuracy, and loss visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dataset
&lt;/h2&gt;

&lt;p&gt;The model uses a labeled dataset of news articles consisting of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Title and Text&lt;/li&gt;
&lt;li&gt;Label: 1 for fake news, 0 for real news&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can easily swap in another dataset or extend it with more complex sources for multilingual or multi-category classification.&lt;/p&gt;

&lt;h2&gt;
  
  
  Model Performance
&lt;/h2&gt;

&lt;p&gt;The model achieves good accuracy in distinguishing real and fake news articles after training with appropriate preprocessing and regularization. Detailed metrics and visual plots are available in the notebook for transparency and fine-tuning. &lt;/p&gt;

&lt;p&gt;This is sample code for &lt;em&gt;detect_fake_news.py&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import pandas as pd
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from sklearn.model_selection import train_test_split
import json
import os

MAX_LENGTH = 500
VOCAB_SIZE = 10000
USER_DATA_PATH = "user_training_data.csv"
FAKE_CSV_PATH = "data/Fake.csv"

def train_model(extra_texts=[], extra_labels=[]):
    # Load base datasets
    df_fake = pd.read_csv(FAKE_CSV_PATH)
    df_fake['label'] = 0

    df_true = pd.read_csv("data/True.csv")
    df_true['label'] = 1

    df = pd.concat([df_fake[['text', 'label']], df_true[['text', 'label']]])

    # Load and include user data if available
    if os.path.exists(USER_DATA_PATH):
        user_df = pd.read_csv(USER_DATA_PATH)
        df = pd.concat([df, user_df], ignore_index=True)

    # Append new user data if provided
    if extra_texts and extra_labels:
        new_data = pd.DataFrame({"text": extra_texts, "label": extra_labels})
        df = pd.concat([df, new_data], ignore_index=True)

        # Append new data to Fake.csv if it is labeled as fake news
        fake_data = new_data[new_data['label'] == 0]  # Only append if label is fake
        if not fake_data.empty:
            fake_data.to_csv(FAKE_CSV_PATH, mode='a', header=False, index=False)

        # Save new data to user_training_data.csv
        new_data.to_csv(USER_DATA_PATH, mode='a', header=not os.path.exists(USER_DATA_PATH), index=False)

    df.dropna(inplace=True)

    # Tokenize and train model
    tokenizer = Tokenizer(num_words=VOCAB_SIZE, oov_token="&amp;lt;OOV&amp;gt;")
    tokenizer.fit_on_texts(df['text'])
    sequences = tokenizer.texts_to_sequences(df['text'])
    padded = pad_sequences(sequences, maxlen=MAX_LENGTH, padding='post', truncating='post')
    X_train, X_test, y_train, y_test = train_test_split(padded, df['label'], test_size=0.2, random_state=42)

    model = tf.keras.Sequential([
        tf.keras.layers.Embedding(VOCAB_SIZE, 16, input_length=MAX_LENGTH),
        tf.keras.layers.GlobalAveragePooling1D(),
        tf.keras.layers.Dense(24, activation='relu'),
        tf.keras.layers.Dense(1, activation='sigmoid')
    ])

    model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
    model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test))

    model.save('fake_or_true_news_model.keras')
    with open("tokenizer.json", "w") as f:
        f.write(tokenizer.to_json())

    print("✅ Model trained and saved successfully.")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;&lt;a href="https://github.com/samseptiano/tensorflow-fake-news-detection/tree/main" rel="noopener noreferrer"&gt;Full Sample Code&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>keras</category>
      <category>tensorflow</category>
    </item>
    <item>
      <title>ReactJS Datatable</title>
      <dc:creator>Samuel S</dc:creator>
      <pubDate>Wed, 23 Apr 2025 13:18:48 +0000</pubDate>
      <link>https://dev.to/samseptiano/reactjs-datatable-cm7</link>
      <guid>https://dev.to/samseptiano/reactjs-datatable-cm7</guid>
      <description>&lt;p&gt;In web applications—especially reporting or monitoring applications—we often need to display a large amount of data from an API. To make data loading faster, we typically design our APIs to support &lt;em&gt;pagination&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In classic &lt;em&gt;JavaScript _frameworks like _&lt;strong&gt;jQuery&lt;/strong&gt;&lt;/em&gt;, we are familiar with using &lt;strong&gt;DataTables&lt;/strong&gt; to display paginated data tables. But how do we use &lt;strong&gt;DataTables&lt;/strong&gt; in &lt;em&gt;ReactJS&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;First, we create react application by executing in our terminal/CMD&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm create-react-app react-demo-datatable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in our terminal/CMD we have to install datatable package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install react-data-table-component
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to install &lt;strong&gt;lodash.debounce&lt;/strong&gt; package for our search data table. &lt;strong&gt;lodash.debounce&lt;/strong&gt; is a utility function from the Lodash library that delays a function’s execution until after a specified amount of time has passed since it was last called. i will prevent Too many API calls (e.g. every user type) to Maximalize performance issue.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install lodash.debounce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then let's adjust our &lt;em&gt;App.js&lt;/em&gt; to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useState, useEffect } from "react";
import DataTable from "react-data-table-component";
import debounce from "lodash.debounce";

// Dummy local dataset
const localData = [
  {
    NO_RESI: "PLMAA16157522113",
    RECEIVER_NAME: "John Doe",
    RECEIVER_DIVISION: "IT",
    CREATED_DATE: "2025-04-11",
    STATUS_NAME: "Complete",
    STATUS: "002",
  },
  {
    NO_RESI: "PLMAA16157522112",
    RECEIVER_NAME: "Jane Doe",
    RECEIVER_DIVISION: "Finance",
    CREATED_DATE: "2025-04-10",
    STATUS_NAME: "On Progress",
    STATUS: "001",
  },
  // Add more dummy items here
];

const statusOptions = [
  { key: "001", status: "On Progress" },
  { key: "002", status: "Complete" },
];

const columns = [
  { name: "No Resi", selector: (row) =&amp;gt; row.NO_RESI, sortable: true },
  { name: "Receiver", selector: (row) =&amp;gt; row.RECEIVER_NAME, sortable: true },
  { name: "Receiver Division", selector: (row) =&amp;gt; row.RECEIVER_DIVISION, sortable: true },
  { name: "Created Date", selector: (row) =&amp;gt; row.CREATED_DATE, sortable: true },
  { name: "Status", selector: (row) =&amp;gt; row.STATUS_NAME, sortable: true },
  {
    name: "Action",
    cell: (row) =&amp;gt; (
      &amp;lt;button className="bg-blue-500 text-black px-3 py-1 rounded hover:bg-blue-600"&amp;gt;
        Detail
      &amp;lt;/button&amp;gt;
    ),
  },
];

const customStyles = {
  headCells: {
    style: {
      backgroundColor: "#919492",
      color: "#333",
      fontWeight: "bold",
      fontSize: "14px",
    },
  },
};

export default function App() {
  const [data, setData] = useState([]);
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("");
  const [loading, setLoading] = useState(false);

  const [totalRows, setTotalRows] = useState(0);
  const [perPage, setPerPage] = useState(10);
  const [currentPage, setCurrentPage] = useState(1);

  const filterLocalData = (page, size, searchText, statusKey) =&amp;gt; {
    setLoading(true);

    let filtered = [...localData];

    if (searchText) {
      filtered = filtered.filter(
        (item) =&amp;gt;
          item.NO_RESI.toLowerCase().includes(searchText.toLowerCase()) ||
          item.RECEIVER_NAME.toLowerCase().includes(searchText.toLowerCase())
      );
    }

    if (statusKey) {
      filtered = filtered.filter((item) =&amp;gt; item.STATUS === statusKey);
    }

    const start = (page - 1) * size;
    const paginated = filtered.slice(start, start + size);

    setData(paginated);
    setTotalRows(filtered.length);
    setLoading(false);
  };

  useEffect(() =&amp;gt; {
    filterLocalData(currentPage, perPage, search, statusFilter);
  }, [search, statusFilter, perPage, currentPage]);

  const handlePageChange = (page) =&amp;gt; {
    setCurrentPage(page);
  };

  const handlePerRowsChange = (newPerPage, page) =&amp;gt; {
    setPerPage(newPerPage);
    setCurrentPage(page);
  };

  const debouncedSearch = debounce((val) =&amp;gt; {
    setSearch(val);
  }, 500);

  return (
    &amp;lt;div className="w-full p-4"&amp;gt;
      &amp;lt;div className="flex justify-between items-center mb-4 gap-4"&amp;gt;
        &amp;lt;select
          className="p-2 border rounded"
          value={statusFilter}
          onChange={(e) =&amp;gt; setStatusFilter(e.target.value)}
        &amp;gt;
          &amp;lt;option value=""&amp;gt;All Status&amp;lt;/option&amp;gt;
          {statusOptions.map((opt) =&amp;gt; (
            &amp;lt;option key={opt.key} value={opt.key}&amp;gt;
              {opt.status}
            &amp;lt;/option&amp;gt;
          ))}
        &amp;lt;/select&amp;gt;

        &amp;lt;input
          type="text"
          placeholder="Search..."
          className="p-2 border rounded w-full max-w-md"
          onChange={(e) =&amp;gt; debouncedSearch(e.target.value)}
        /&amp;gt;
      &amp;lt;/div&amp;gt;

      &amp;lt;DataTable
        columns={columns}
        data={data}
        progressPending={loading}
        pagination
        paginationServer
        paginationTotalRows={totalRows}
        onChangePage={handlePageChange}
        onChangeRowsPerPage={handlePerRowsChange}
        customStyles={customStyles}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our react project will look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffegooutlr1096x7gqjl1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffegooutlr1096x7gqjl1.png" alt="Demo App" width="800" height="203"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>datatable</category>
      <category>pagination</category>
    </item>
    <item>
      <title>Code Rabbit - AI Code Reviewer for Git</title>
      <dc:creator>Samuel S</dc:creator>
      <pubDate>Tue, 25 Mar 2025 13:58:32 +0000</pubDate>
      <link>https://dev.to/samseptiano/code-rabbit-ai-code-reviewer-for-git-21fa</link>
      <guid>https://dev.to/samseptiano/code-rabbit-ai-code-reviewer-for-git-21fa</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgilgdvopom2mmna3k5v1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgilgdvopom2mmna3k5v1.png" alt="Code rabbit Homepage" width="800" height="334"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Nowadays, AI really helps our work, especially in the world of software engineering. Did you know that there are AI-based tools that can help us review our code in GIT? yes, it is &lt;strong&gt;CodeRabbit&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to try, you can visit:&lt;br&gt;
&lt;a href="https://www.coderabbit.ai/" rel="noopener noreferrer"&gt;https://www.coderabbit.ai/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, you must sign up to create account.&lt;/p&gt;

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

&lt;p&gt;I recommend you to sign up by your git account.&lt;/p&gt;

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

&lt;p&gt;This is sign up dashboard. Then, we click &lt;strong&gt;Add Repositories&lt;/strong&gt;&lt;/p&gt;

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

&lt;p&gt;Choose where you want to choose to install. I will install at my **samseptiano **account&lt;/p&gt;

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

&lt;p&gt;At bottom of page, select repos you want to integrate. you can choose to integrate &lt;strong&gt;all repos&lt;/strong&gt;, or &lt;strong&gt;selected repos&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;Then, I try to make a pull request from one branch to master. &lt;br&gt;
Wait for minutes, soon Code Rabbit AI will give you some reviews about your pull request.&lt;/p&gt;

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

&lt;p&gt;So easy to integrate, isn't it? please let me know if this tools ease you! :)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>git</category>
      <category>code</category>
    </item>
    <item>
      <title>Koin Vs Hilt</title>
      <dc:creator>Samuel S</dc:creator>
      <pubDate>Sun, 16 Mar 2025 06:14:45 +0000</pubDate>
      <link>https://dev.to/samseptiano/koin-vs-hilt-3jek</link>
      <guid>https://dev.to/samseptiano/koin-vs-hilt-3jek</guid>
      <description>&lt;p&gt;In &lt;strong&gt;object-oriented programming (OOP)&lt;/strong&gt;, especially in &lt;em&gt;Android Development&lt;/em&gt;, to make our program code cleaner and maintainable, one of the principles we are used to apply is &lt;strong&gt;&lt;a href="https://simple.wikipedia.org/wiki/SOLID_(object-oriented_design)" rel="noopener noreferrer"&gt;SOLID&lt;/a&gt;&lt;/strong&gt;. one of the points in the SOLID principle is &lt;strong&gt;Dependency Inversion&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;One should depend upon abstractions, not concretions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Inversion_of_control" rel="noopener noreferrer"&gt;Inversion of Control (IoC)&lt;/a&gt;&lt;/strong&gt; is a design pattern used to represent Dependency Inversion in real software.&lt;/p&gt;

&lt;p&gt;That makes Dependency Injection popular.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Dependency Injection?
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Dependency injection&lt;/em&gt; (DI) is a software engineering technique that involves making the interactions between objects as thin as possible through specific dependencies. This allows for loosely coupled code — or code that only depends on the required portion of a separate class — to run. And it reduces hard-coded dependencies and allows for cleaner, more flexible code.&lt;/p&gt;

&lt;p&gt;some of most popular Dependency Injection frameworks are &lt;strong&gt;Koin&lt;/strong&gt; and &lt;strong&gt;Hilt&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;Then what's different?&lt;/p&gt;

&lt;p&gt;Let’s start by talking about Koin first.&lt;/p&gt;

&lt;p&gt;Koin stands out for its simplicity and flexibility. It is a simple DI framework that does not require annotations or code generation. Instead, it makes use of the Domain Specific Language (DSL) provided by Kotlin to specify dependencies and modules.&lt;/p&gt;

&lt;p&gt;Koin’s ease of use is one of its benefits. Its minimum setup requirements and its ability to create dependencies with a clear, readable syntax are the aspects that make it stand out. Therefore, Koin is easy for developers who are new to DI.&lt;/p&gt;

&lt;p&gt;On the other hand, this features of Koin might come with trade-offs in certain scenarios. Its runtime resolution might lead to potential issues during compile-time if dependencies are not properly configured. Additionally, Koin might not offer the same level of performance optimizations that some other DI frameworks, like Hilt, provide.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use Koin?
&lt;/h2&gt;

&lt;p&gt;First, add dependencies to our project’s &lt;em&gt;build.gradle&lt;/em&gt; file,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    // Koin core features
    implementation 'org.koin:koin-core:3.2.0'

    // Koin Android features
    implementation 'org.koin:koin-android:3.2.0'
    implementation 'org.koin:koin-androidx-viewmodel:3.2.0'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, create Koin modules,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import org.koin.dsl.module

val myKoinModule = module {
    single { UserRepository() } 
    factory { UserViewModel(get()) }
    // Define other dependencies...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;single&lt;/strong&gt;: create an object that persistent with the entire container lifetime. It does not create a new instance with each call.&lt;br&gt;
&lt;strong&gt;factory&lt;/strong&gt;: create a new object each time. Short live. No persistence in the container&lt;/p&gt;

&lt;p&gt;Then in Application class, initialize Koin by loading the modules,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class MyKoinApplication : Application() {
    override fun onCreate() {
        super.onCreate()
        startKoin {
            androidContext(this@MyKoinApplication )
            modules(myKoinModule )
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is how we call at Activity&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class HomeActivity : AppCompatActivity() {
    private val viewModel by viewModel&amp;lt;UserViewModel&amp;gt;()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        // Use viewModel or other dependencies...
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;how about Hilt?&lt;/p&gt;

&lt;p&gt;Hilt, developed by Google and built on top of Dagger, is a powerful dependency injection (DI) framework tailored for Android. It simplifies DI by leveraging annotations and compile-time checks to ensure correctness and performance. Additionally, it integrates seamlessly with Jetpack libraries like ViewModel and WorkManager, making it easier to manage dependencies across different Android components.&lt;/p&gt;

&lt;p&gt;One of Hilt’s biggest advantages is its strong alignment with the Android development ecosystem, making it a preferred choice for larger projects following architectural patterns like MVVM or Clean Architecture. However, its learning curve can be steep due to its reliance on Dagger and the specific annotations required. Compared to Koin, Hilt may also involve a more complex setup, but it offers better compile-time safety and performance benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use Hilt
&lt;/h2&gt;

&lt;p&gt;Add Hilt dependency at our project’s &lt;em&gt;build.gradle&lt;/em&gt; file,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies {
    // Other dependencies...
    implementation "com.google.dagger:hilt-android:$hilt_version"
    kapt "com.google.dagger:hilt-compiler:$hilt_version"
    implementation "androidx.hilt:hilt-lifecycle-viewmodel:$hilt_lifecycle_version"
    kapt "androidx.hilt:hilt-compiler:$hilt_lifecycle_version"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable Hilt to our Application&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@HiltAndroidApp
class MyHiltApplication : Application()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Creating Hilt modules&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@Module
@InstallIn(ApplicationComponent::class)
object MyModule {
    @Provides
    fun provideMyRepository(): MyRepository {
        return MyRepository()
    }

    @Provides
    fun provideMyViewModel(repository: MyRepository): MyViewModel {
        return MyViewModel(repository)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using dependencies in Activity/Fragment,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@AndroidEntryPoint
class MyActivity : AppCompatActivity() {
    private val viewModel: MyViewModel by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;There is 3 different characteristics between Koin and Hilt:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax and Configuration:&lt;/strong&gt; Koin offers a simple and readable syntax without relying on annotations or code generation, while Hilt heavily depends on annotations like @Inject and @Module for dependency injection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Learning Curve and Complexity:&lt;/strong&gt; Koin is beginner-friendly with minimal setup, making it easier to adopt. In contrast, Hilt has a steeper learning curve due to its integration with Dagger and required annotations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance and Optimization:&lt;/strong&gt; Koin has faster build times and a smaller APK size since it doesn’t generate code, but it is slightly slower at runtime due to resolving dependencies dynamically. Hilt, using code generation, ensures better runtime performance but can lead to longer build times and a larger APK.&lt;/p&gt;

&lt;h2&gt;
  
  
  So when to use Koin and Hilt?
&lt;/h2&gt;

&lt;p&gt;_Koin _is ideal for smaller projects due to its simplicity and flexibility, making code more modular and maintainable. However, for larger projects requiring deep integration with Android components, _Hilt _is preferable for its performance optimizations and alignment with Android architecture.&lt;/p&gt;




&lt;p&gt;references: &lt;br&gt;
&lt;em&gt;&lt;a href="https://medium.com/ibtech/hilt-vs-koin-f3532b5796eb" rel="noopener noreferrer"&gt;https://medium.com/ibtech/hilt-vs-koin-f3532b5796eb&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Dependency_injection" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Dependency_injection&lt;/a&gt;&lt;br&gt;
&lt;a href="https://simple.wikipedia.org/wiki/SOLID" rel="noopener noreferrer"&gt;https://simple.wikipedia.org/wiki/SOLID&lt;/a&gt;&lt;/em&gt;(object-oriented_design)_&lt;br&gt;
&lt;a href="https://medium.com/@srimanikandan92/hilt-vs-koin-a-simple-guide-to-android-dependency-injection-ef77d00e7cf6" rel="noopener noreferrer"&gt;https://medium.com/@srimanikandan92/hilt-vs-koin-a-simple-guide-to-android-dependency-injection-ef77d00e7cf6&lt;/a&gt;&lt;/p&gt;

</description>
      <category>android</category>
      <category>solidprinciples</category>
      <category>dependencyinversion</category>
    </item>
    <item>
      <title>Getting started to Flutter Provider</title>
      <dc:creator>Samuel S</dc:creator>
      <pubDate>Mon, 03 Apr 2023 05:04:28 +0000</pubDate>
      <link>https://dev.to/samseptiano/getting-started-to-flutter-provider-1747</link>
      <guid>https://dev.to/samseptiano/getting-started-to-flutter-provider-1747</guid>
      <description>&lt;h2&gt;
  
  
  What is Provider?
&lt;/h2&gt;

&lt;p&gt;Provider is one of the many state management options when using Flutter. It’s one of the first state manager recommended by Flutter itself and one of the simplest. If you’re new to state management check out the official pages that describes the different state managers and how/when you should use it &lt;a href="https://flutter.dev/docs/development/data-and-backend/state-mgmt/options" rel="noopener noreferrer"&gt;https://flutter.dev/docs/development/data-and-backend/state-mgmt/options&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Provider can do?
&lt;/h2&gt;

&lt;p&gt;Provider can be used with &lt;code&gt;InheritedWidgets&lt;/code&gt;and &lt;code&gt;StatefulWidgets&lt;/code&gt;, or again, in place of them. It "does" two jobs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Separates your state from your UI&lt;/li&gt;
&lt;li&gt;Manages rebuilding UI based on state changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Providers allow to not only expose a value, but also create/listen/dispose it.&lt;/strong&gt; &lt;a href="https://pub.dev/packages/provider" rel="noopener noreferrer"&gt;source&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Dependencies
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dependencies:
  flutter:
    sdk: flutter
  cupertino_icons: ^1.0.2
  provider: ^6.0.5
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's Start Write our codes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Create Our Provider&lt;/strong&gt;&lt;br&gt;
create a file called &lt;code&gt;notes_operation.dart&lt;/code&gt;, and add this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class NotesOperation with ChangeNotifier {
  //List of notes
  List&amp;lt;Note&amp;gt; _notes = [];

  List&amp;lt;Note&amp;gt; get getNotes {
    return _notes;
  }

  NotesOperation() {
    //addNewNote('First Note', 'First Note Description');
  }

  void addNewNote(String title, String description) {
    //Note object
    Note note = Note(title, description);
    _notes.add(note);
    notifyListeners();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;It extends &lt;code&gt;ChangeNotifier&lt;/code&gt;, a class that “provides change notification to its listeners”. So you can listen to an instance of a &lt;code&gt;ChangeNotifier&lt;/code&gt;and being notified when it changes.&lt;/li&gt;
&lt;li&gt;It exposes the list of notes value which start with empty list.&lt;/li&gt;
&lt;li&gt;We will use the &lt;code&gt;addNewNote&lt;/code&gt;function to add note.&lt;/li&gt;
&lt;li&gt;When the note added to list, changes the class will notify its listener using &lt;code&gt;notifyListeners()&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now we will need to add the Provider widget in our widget tree, in our case all the children of the &lt;code&gt;homeScreen&lt;/code&gt; should display list of notes, so we sill need to wrap the &lt;code&gt;HomeScreen&lt;/code&gt; widget in a Provider widget (in particular a &lt;code&gt;ChangeNotifierProvider&lt;/code&gt; because we're using a ChangeNotifier). &lt;code&gt;ChangeNotifierProvider&lt;/code&gt; needs a create parameter, it's the function that will be called to create our &lt;code&gt;NoteOperation&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class HomeScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      backgroundColor: Colors.blueGrey,
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          Navigator.push(
            context,
            MaterialPageRoute(
              builder: (context) =&amp;gt; AddScreen(),
            ),
          );
        },
        child: Icon(Icons.add, size: 30, color: Colors.blueGrey),
        backgroundColor: Colors.white,
      ),
      appBar: AppBar(
        title: Text(
          'Task Manager',
          style: TextStyle(
            fontSize: 25,
            fontWeight: FontWeight.bold,
          ),
        ),
        centerTitle: true,
        elevation: 0,
        backgroundColor: Colors.transparent,
      ),
      body: Consumer&amp;lt;NotesOperation&amp;gt;(
        builder: (context, NotesOperation data, child) {
          return ListView.builder(
            itemCount: data.getNotes.length,
            itemBuilder: (context, index) {
              return NotesCard(data.getNotes[index]);
            },
          );
        },
      ),
    );
  }
}

class NotesCard extends StatelessWidget {
  final Note note;

  NotesCard(this.note);

  @override
  Widget build(BuildContext context) {
    return Container(
      margin: EdgeInsets.all(15),
      padding: EdgeInsets.all(15),
      height: 150,
      decoration: BoxDecoration(
        color: Colors.white,
        borderRadius: BorderRadius.circular(15),
      ),
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Text(
            note.title,
            style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
          ),
          SizedBox(height: 5),
          Text(
            note.description,
            style: TextStyle(fontSize: 17),
          ),
        ],
      ),
    );
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can display list of notes of out &lt;code&gt;NotesOperation&lt;/code&gt;, to do so we need to use a Consumer widget.&lt;/p&gt;

&lt;p&gt;The Consumer widget has a builder function that is called whenever the Provider needs to (basically when &lt;code&gt;notifyListeners&lt;/code&gt;is called). The builder function has 3 parameters:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;context&lt;/code&gt;: the context of this build&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;NotesOperation&lt;/code&gt;: our NotesOperation declared above. If the provider package doesn't find a parent with the correct Provider type it will throw an Exception.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;child&lt;/code&gt;: you can optionally pass a child widget to the Consumer, that will be passed to the builder function in this parameter. This is here for optimization, if you have a big widget that doesn’t need the value exposed by the provider you can pass it as child and use it in the builder function.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here’s an example of a text that display list of notes of our &lt;code&gt;NotesOperation&lt;/code&gt; .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Consumer&amp;lt;NotesOperation&amp;gt;(
        builder: (context, NotesOperation data, child) {
          return ListView.builder(
            itemCount: data.getNotes.length,
            itemBuilder: (context, index) {
              return NotesCard(data.getNotes[index]);
            },
          );
        },
      )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why don’t you just call setState?
&lt;/h2&gt;

&lt;p&gt;The obvious question that could come to your mind is “Why don’t you just use a StatefulWidget with setState?”. Here are some of the reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;One of the main reasons to prefer &lt;code&gt;Provider&lt;/code&gt;over &lt;code&gt;Statefulwidgets&lt;/code&gt;is that, using &lt;code&gt;Provider&lt;/code&gt;, you will rebuild only the widgets that needs that value (the &lt;code&gt;Consumers&lt;/code&gt;) while the other will not be rebuilt. Instead when you call &lt;code&gt;setState&lt;/code&gt; the whole build function of the widget will be called.&lt;/li&gt;
&lt;li&gt;You can use the values exposed by providers in other widgets without passing them. In our case, if you need to push a new Scaffold you can still use the mainColor with the Consumer because it will be a child of the Provider&lt;/li&gt;
&lt;li&gt;You can have different Providers, that do different things using a &lt;a href="https://pub.dev/packages/provider#multiprovider" rel="noopener noreferrer"&gt;MultiProvider&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;The allocation and disposal of objects is managed by the package and the objects are created lazily when they are needed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;full example: &lt;a href="https://github.com/samseptiano/flutter-note-app" rel="noopener noreferrer"&gt;github&lt;/a&gt;&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>provider</category>
      <category>mobile</category>
      <category>dart</category>
    </item>
  </channel>
</rss>
