<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[ankeetblog]]></title><description><![CDATA[I love to code.]]></description><link>https://tejbikram.com.np</link><generator>RSS for Node</generator><lastBuildDate>Sun, 06 Sep 2026 21:02:54 GMT</lastBuildDate><atom:link href="https://tejbikram.com.np/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Running JavaScript Code in Flutter Webview]]></title><description><![CDATA[Have you ever used the webview_flutter package? It's awesome. You can render web view with ease. Have you ever stumbled upon a requirement when you had to run custom JavaScript code in Flutter on a certain website with or without rendering the websit...]]></description><link>https://tejbikram.com.np/running-javascript-code-in-flutter-webview</link><guid isPermaLink="true">https://tejbikram.com.np/running-javascript-code-in-flutter-webview</guid><category><![CDATA[Flutter]]></category><category><![CDATA[flutterwebview]]></category><category><![CDATA[webview_flutter]]></category><category><![CDATA[#javascriptflutter]]></category><category><![CDATA[#javascriptinjection]]></category><dc:creator><![CDATA[Ankeet Karki]]></dc:creator><pubDate>Sat, 03 Jun 2023 12:35:49 GMT</pubDate><content:encoded><![CDATA[<p>Have you ever used the <a target="_blank" href="https://pub.dev/packages/webview_flutter">webview_flutter</a> package? It's awesome. You can render web view with ease. Have you ever stumbled upon a requirement when you had to run custom JavaScript code in Flutter on a certain website with or without rendering the website?</p>
<p>You might already know about <code>WebViewController().runJavaScript()</code> method. Let's dive deep into it.</p>
<p>Let us suppose, We need to scrape certain data from a website and you need to render those in your Flutter app. In my case, I'm using my friend Nirav's website: <a target="_blank" href="https://niravko.com">https://niravko.com</a>. I'm going to scrape all the titles of the blogs that he has posted so far. Firstly, I need to head to his website in the browser and write custom javascript codes to fetch all the titles as displayed below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1685792499462/31dc267a-b872-4a43-bfee-176b2aa67261.png" alt class="image--center mx-auto" /></p>
<p>This JavaScript code runs fine in the browser. Now, we need to implement it in the app.</p>
<p>First, create a Flutter app, and add <a target="_blank" href="https://pub.dev/packages/webview_flutter">webview_flutter</a> in pubspec.yaml file and run <code>flutter pub get</code>.</p>
<p>Make a new screen where you need to display the data scraped (HomePage in my case).</p>
<p>Add these codes in the initState method your <code>HomePage()</code>  </p>
<pre><code class="lang-dart">  <span class="hljs-keyword">late</span> WebViewController _controller;
  <span class="hljs-built_in">String?</span> message;


 <span class="hljs-meta">@override</span>
  <span class="hljs-keyword">void</span> initState() {
    _controller = WebViewController()
      ..setJavaScriptMode(JavaScriptMode.unrestricted)
      ..loadRequest(<span class="hljs-built_in">Uri</span>.parse(<span class="hljs-string">"https://niravko.com"</span>))
      ..addJavaScriptChannel(<span class="hljs-string">"myChannel"</span>,
          onMessageReceived: (JavaScriptMessage message) {
        setMessage(message.message);
      })
      ..setNavigationDelegate(
        NavigationDelegate(
          onPageFinished: (<span class="hljs-built_in">String</span> url) {
            injectJavascript(_controller);
          },
        ),
      );

    <span class="hljs-keyword">super</span>.initState();
  }
</code></pre>
<p>You need to initialize the web controller with the above properties. To run the JavaScript you need to set JavaScript mode as unrestricted with <code>setJavascriptMode(JavaScriptMode.unrestricted)</code> and to listen to the message that is to be passed via running JavaScript to the Flutter app, you need to add a JavaScript channel with some name and you can receive the message that is passed via JavaScript code.</p>
<p>The <code>setMessage</code> function sets the <code>message</code> variable with the String passed through JavaScript.</p>
<pre><code class="lang-dart"> setMessage(<span class="hljs-built_in">String</span> javascriptMessage) {
    <span class="hljs-keyword">if</span> (mounted) {
      setState(() {
        message = javascriptMessage;
      });
    }
  }
</code></pre>
<p>Inside the <code>injectJavaScript</code> function, We need to run the JavaScript code that we were running earlier in the browser. The only additional thing to the previous code is we need to notify our JavaScript channel i.e. <code>myChannel</code> with the message in <code>String</code> form i.e. <code>myChannel.postMessage(message)</code> is enough to send a message to the channel that we set up earlier.</p>
<pre><code class="lang-javascript">
  injectJavascript(WebViewController controller) <span class="hljs-keyword">async</span> {
    controller.runJavaScript(<span class="hljs-string">''</span><span class="hljs-string">'
   const items = Array.from(document.getElementsByClassName("Post_title__MJ8Hr __className_ff0aba"));
   function getTitle(data){
        return data.textContent.trim();
    }
    const titleList = items.map(getTitle);
    //nameList is the list of titles that we scraped.
    myChannel.postMessage(JSON.stringify(titleList));
'</span><span class="hljs-string">''</span>);
  }
</code></pre>
<p>The basic flow is that once the website is rendered completely, the channel is set up and the JavaScript code is run and when <code>myChannel.postMessage</code> is triggered, then <code>setMessage</code> function is triggered and the message variable is set with the <code>titleList</code> in String form.</p>
<p>Now to display the fetched title list, we can add the following code in the build method of <code>HomePage</code>.</p>
<pre><code class="lang-dart"> <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      body: message == <span class="hljs-keyword">null</span>
          ? <span class="hljs-keyword">const</span> Center(
              child: CircularProgressIndicator(),
            )
          : Builder(
              builder: (context) {
                <span class="hljs-built_in">List</span>&lt;<span class="hljs-built_in">dynamic</span>&gt; items = jsonDecode(message!);
                <span class="hljs-keyword">return</span> ListView.builder(
                  itemCount: items.length,
                  itemBuilder: (context, index) {
                    <span class="hljs-keyword">return</span> ListTile(
                      title: Text(items[index]),
                    );
                  },
                );
              },
            ),
    );
  }
</code></pre>
<p>Now, the result will be displayed as shown below:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1685793926930/c807190a-53ef-4b8b-b5b5-ebbb0800f6a0.png" alt class="image--center mx-auto" /></p>
<p>And you're done :)</p>
<p>The full source code is available at: <a target="_blank" href="https://github.com/ankeet7x/javascript_injection_in_flutter_webview">https://github.com/ankeet7x/javascript_injection_in_flutter_webview</a></p>
]]></content:encoded></item><item><title><![CDATA[Implement customized scrolling in your Flutter App]]></title><description><![CDATA[Do you want to implement custom scrolling in your Flutter application where you can position specific widgets at the top of your device like this?
https://www.youtube.com/shorts/QoJ08Wwa0l0
 
It's really easy to implement using CustomScrollView.
Firs...]]></description><link>https://tejbikram.com.np/implement-customized-scrolling-in-your-flutter-app</link><guid isPermaLink="true">https://tejbikram.com.np/implement-customized-scrolling-in-your-flutter-app</guid><category><![CDATA[Flutter]]></category><category><![CDATA[Flutter Examples]]></category><category><![CDATA[Flutter Widgets]]></category><category><![CDATA[flutter scrolling]]></category><category><![CDATA[custom scrolling in flutter]]></category><dc:creator><![CDATA[Ankeet Karki]]></dc:creator><pubDate>Fri, 10 Feb 2023 17:06:07 GMT</pubDate><content:encoded><![CDATA[<p>Do you want to implement custom scrolling in your Flutter application where you can position specific widgets at the top of your device like this?</p>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/shorts/QoJ08Wwa0l0">https://www.youtube.com/shorts/QoJ08Wwa0l0</a></div>
<p> </p>
<p>It's really easy to implement using CustomScrollView.</p>
<p>First, create a new project using <code>flutter create project_name</code></p>
<p>Now, open it in your desired code editor. Navigate to the lib folder and copy the following content into your main.dart file.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:custom_scroll/home_page.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;


<span class="hljs-keyword">void</span> main(){
  runApp(<span class="hljs-keyword">const</span> MyApp());
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
  <span class="hljs-keyword">const</span> MyApp({<span class="hljs-keyword">super</span>.key});

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">const</span> MaterialApp(
      title: <span class="hljs-string">"custom scroll"</span>,
      home: HomePage(),
    );
  }
}
</code></pre>
<p>Now, create a new file named home_page.dart inside your lib folder and copy the following block of code inside that file.</p>
<pre><code class="lang-dart"><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HomePage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatefulWidget</span> </span>{
  <span class="hljs-keyword">const</span> HomePage({<span class="hljs-keyword">super</span>.key});

  <span class="hljs-meta">@override</span>
  State&lt;HomePage&gt; createState() =&gt; _HomePageState();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_HomePageState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">HomePage</span>&gt; </span>{
  Widget horizontalList() {
    <span class="hljs-keyword">return</span> SingleChildScrollView(
      scrollDirection: Axis.horizontal,
      child: Row(
        children: [
          <span class="hljs-string">"First"</span>,
          <span class="hljs-string">"Second"</span>,
          <span class="hljs-string">"Third"</span>,
          <span class="hljs-string">"Fourth"</span>,
          <span class="hljs-string">"Fifth"</span>,
          <span class="hljs-string">"Sixth"</span>,
          <span class="hljs-string">"Seventh"</span>,
        ]
            .map((e) =&gt; Padding(
                  padding: <span class="hljs-keyword">const</span> EdgeInsets.symmetric(horizontal: <span class="hljs-number">10</span>),
                  child: Chip(
                    label: Text(e.toString()),
                  ),
                ))
            .toList(),
      ),
    );
  }

  <span class="hljs-meta">@override</span>
  Widget build(BuildContext context) {
    <span class="hljs-keyword">return</span> Scaffold(
      appBar: AppBar(),
      body: CustomScrollView(
        slivers: [
          SliverToBoxAdapter(
            child: horizontalList(),
          ),
          SliverAppBar(
            title: horizontalList(),
            pinned: <span class="hljs-keyword">true</span>,
            titleSpacing: <span class="hljs-number">0</span>,
            backgroundColor: Theme.of(context).scaffoldBackgroundColor,
          ),
          SliverToBoxAdapter(
            child: horizontalList(),
          ),
          SliverAppBar(
            title: horizontalList(),
            pinned: <span class="hljs-keyword">true</span>,
            titleSpacing: <span class="hljs-number">0</span>,
            backgroundColor: Theme.of(context).scaffoldBackgroundColor,
          ),
          SliverToBoxAdapter(
            child: ListView.separated(
              physics: <span class="hljs-keyword">const</span> NeverScrollableScrollPhysics(),
              separatorBuilder: ((context, index) =&gt; <span class="hljs-keyword">const</span> SizedBox(
                    height: <span class="hljs-number">5</span>,
                  ),
                ),
              shrinkWrap: <span class="hljs-keyword">true</span>,
              itemCount: <span class="hljs-number">50</span>,
              itemBuilder: (context, index) {
                <span class="hljs-keyword">return</span> Container(
                  height: <span class="hljs-number">50</span>,
                  alignment: Alignment.center,
                  color: Colors.yellow,
                  width: <span class="hljs-built_in">double</span>.infinity,
                  child: Text(<span class="hljs-string">"<span class="hljs-subst">$index</span>"</span>),
                );
              },
            ),
          )
        ],
      ),
    );
  }
}
</code></pre>
<p>Great! We've just implemented the scrolling displayed above in the embedded video.</p>
<p>Let me explain a few points:</p>
<ul>
<li><p>The widget you want to pin must be contained in a SliverAppBar as the SliverAppBar contains a pinned property, that helps you to pin/unpin specific widgets as per your choice.</p>
</li>
<li><p>The other normally used widgets such as Container, ListView, Column, etc must be wrapped by SliverAppBar/SliverFillRemaining/SliverToBoxAdapter or something else which I currently don't know of, otherwise, you might encounter an error telling: <code>A RenderViewport expected a child of type RenderSliver but received a child of type RenderRepaintBoundary.</code></p>
</li>
</ul>
<p>With these points in mind, you can make this effect in just a few minutes. The source code is available at: <a target="_blank" href="https://github.com/ankeet7x/custom_scroll">https://github.com/ankeet7x/custom_scroll</a></p>
<p>P.S. This is a way I implement it. If you guys know of some other ways, feel free to advice. Thanks :)</p>
]]></content:encoded></item><item><title><![CDATA[Switch themes easily in Flutter using Bloc]]></title><description><![CDATA[As a user of any application, We try to switch between the themes and choose which the theme that we like the most and as a mobile app developer, We should give our application users a flexibility to switch between themes which improves user experien...]]></description><link>https://tejbikram.com.np/switch-themes-easily-in-flutter-using-bloc</link><guid isPermaLink="true">https://tejbikram.com.np/switch-themes-easily-in-flutter-using-bloc</guid><category><![CDATA[fluttertheme]]></category><category><![CDATA[flutter_bloc]]></category><category><![CDATA[Flutter]]></category><dc:creator><![CDATA[Ankeet Karki]]></dc:creator><pubDate>Sat, 08 Oct 2022 14:43:45 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1665240148083/c7kBsqMAD.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>As a user of any application, We try to switch between the themes and choose which the theme that we like the most and as a mobile app developer, We should give our application users a flexibility to switch between themes which improves user experience.</p>
<p>Here, We're going to learn theme switching using Bloc as state management.</p>
<p>First, create a new app using 
<code>flutter create appname</code>  and open it in IDE of your preference.</p>
<p>Well, in your pubspec.yaml file add </p>
<pre><code>  shared_preferences: ^<span class="hljs-number">2.0</span><span class="hljs-number">.15</span>
  <span class="hljs-attr">flutter_bloc</span>: ^<span class="hljs-number">8.1</span><span class="hljs-number">.1</span>
</code></pre><p>Flutter bloc is for state management while shared preferences is for saving theme locally so that while opening app next time, we can check which theme is activated and then set the theme.</p>
<p>Add a new extension bloc from store in your IDE and then right click the lib folder and then click option new bloc and then give bloc a name of theme. A new folder with name theme_bloc will be generated.</p>
<p>Now remove theme_state file from the folder and you'll get this folder file structure and also a few errors.
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1665237222364/QK6ZWlQj4.png" alt="Screen Shot 2022-10-08 at 19.38.05.png" /></p>
<p>Now, go to <code>theme_bloc.dart</code> file and you'll see errors in ThemeState as theme state is not recognized since we've removed the file. Replace that ThemeState by ThemeData. Import necessary imports and remove unrecognized and unnecessary imports. You'll get this:</p>
<pre><code>      <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThemeBloc</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Bloc</span>&lt;<span class="hljs-title">ThemeEvent</span>, <span class="hljs-title">ThemeData</span>&gt; </span>{
        ThemeBloc() : <span class="hljs-built_in">super</span>(ThemeData.light()) {
         on&lt;ThemeEvent&gt;((event, emit){});
        }
</code></pre><p>Now, our ThemeBloc's state will be of ThemeData type i.e. when we emit state in this bloc, we'll have to emit state in for ThemeData.light(), ThemeData.dark(), etc.</p>
<p>Now in <code>theme_event.dart</code> file add two events. ThemeSwitchEvent and InitialThemeSetEvent extending ThemeEvent like this:</p>
<pre><code>  part <span class="hljs-keyword">of</span> <span class="hljs-string">'theme_bloc.dart'</span>;

  @immutable
  abstract <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThemeEvent</span> </span>{}

  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">InitialThemeSetEvent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ThemeEvent</span> </span>{}

  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThemeSwitchEvent</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">ThemeEvent</span> </span>{}
</code></pre><p>Now, We're going to handle the logic in <code>theme_bloc.dart</code> file as per our event. Firstly, let's work on ThemeSwitchEvent. The main use case is: When a user clicks a switch that is used to change theme, we need to add this event. And when this event is triggered, we need to check what theme is currently activated and we need to change the theme to dark if light is activated currently and to light if dark is activated and We'll also need to add certain value to shared preferences in such a way that we can identify what theme is currently activated in the app so that when user restarts the app, we can activate that theme initially. This initial theme setting logic is handled by the InitialThemeSetEvent.</p>
<p>Now, create a file <code>theme_helper.dart</code> just to add two functions to set bool value in shared preferences with key "is_dark" that keeps a value true if theme is dark and false if theme is true.</p>
<p>In <code>theme_helper.dart</code> file add this two functions:</p>
<pre><code>
  Future&lt;bool&gt; isDark() <span class="hljs-keyword">async</span> {
    final SharedPreferences prefs = <span class="hljs-keyword">await</span> SharedPreferences.getInstance();
    <span class="hljs-keyword">return</span> prefs.getBool(<span class="hljs-string">"is_dark"</span>) ?? <span class="hljs-literal">false</span>;
  }

  Future&lt;<span class="hljs-keyword">void</span>&gt; setTheme(bool isDark) <span class="hljs-keyword">async</span> {
    final SharedPreferences prefs = <span class="hljs-keyword">await</span> SharedPreferences.getInstance();
    prefs.setBool(<span class="hljs-string">"is_dark"</span>, !isDark);
  }
</code></pre><p>The function isDark() which is called while opening the app returns true if the value inside the key "is_dark" is true and false if value is false or null. The setTheme function is triggered once the theme is updated after clicking the switch i.e. on ThemeSwitchEvent.</p>
<p>Now, update your <code>theme_bloc.dart</code> file like this to update theme.</p>
<pre><code>  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">ThemeBloc</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Bloc</span>&lt;<span class="hljs-title">ThemeEvent</span>, <span class="hljs-title">ThemeData</span>&gt; </span>{
    ThemeBloc() : <span class="hljs-built_in">super</span>(ThemeData.light()) {
      <span class="hljs-comment">//when app is started</span>
      on&lt;InitialThemeSetEvent&gt;((event, emit) <span class="hljs-keyword">async</span> {
        final bool hasDarkTheme = <span class="hljs-keyword">await</span> isDark();
        <span class="hljs-keyword">if</span> (hasDarkTheme) {
          emit(ThemeData.dark());
        } <span class="hljs-keyword">else</span> {
          emit(ThemeData.light());
        }
      });

      <span class="hljs-comment">//while switch is clicked</span>
      on&lt;ThemeSwitchEvent&gt;((event, emit) {
        final isDark = state == ThemeData.dark();
        emit(isDark ? ThemeData.light() : ThemeData.dark());
        setTheme(isDark);
      });
    }
  }
</code></pre><p>Now the logic is handled here in <code>theme_bloc.dart</code>. Now you need to call the events in the app and it is necessary to understand where to call the event.</p>
<p>The theme your app is currently using can be switched from <code>MaterialApp</code> where we give <code>theme</code> property. So we need to provide MaterialApp with our state as our state is currently activated theme. Now, Wrap <code>MaterialApp</code> with <code>BlocBuilder</code> of <code>ThemeBloc</code> after clicking (Control + .)/(Command + .). In <code>theme</code> key of MaterialApp give state as value as in our <code>ThemeBloc</code> state means <code>ThemeData</code>. The result will be like this:</p>
<pre><code>  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">MyApp</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatelessWidget</span> </span>{
    <span class="hljs-keyword">const</span> MyApp({<span class="hljs-built_in">super</span>.key});

    @override
    Wid<span class="hljs-keyword">get</span> <span class="hljs-title">build</span>(<span class="hljs-params">BuildContext context</span>) {
      <span class="hljs-keyword">return</span> BlocBuilder&lt;ThemeBloc, ThemeData&gt;(
        builder: (context, state) {
          <span class="hljs-keyword">return</span> MaterialApp(
            theme: state,
            <span class="hljs-attr">debugShowCheckedModeBanner</span>: <span class="hljs-literal">false</span>,
            <span class="hljs-attr">home</span>: <span class="hljs-keyword">const</span> HomePage(),
          );
        },
      );
    }
  }
</code></pre><p>Create home.dart inside lib folder and in the content of <code>HomePage</code> add this content:</p>
<pre><code><span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/cupertino.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter/material.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:flutter_bloc/flutter_bloc.dart'</span>;
<span class="hljs-keyword">import</span> <span class="hljs-string">'package:theme_switcher/bloc/theme_bloc.dart'</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">HomePage</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">StatefulWidget</span> </span>{
  <span class="hljs-keyword">const</span> HomePage({<span class="hljs-built_in">super</span>.key});

  @override
  State&lt;HomePage&gt; createState() =&gt; _HomePageState();
}

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">_HomePageState</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">State</span>&lt;<span class="hljs-title">HomePage</span>&gt; </span>{
  @override
  Wid<span class="hljs-keyword">get</span> <span class="hljs-title">build</span>(<span class="hljs-params">BuildContext context</span>) {
    <span class="hljs-keyword">return</span> Scaffold(
      appBar: AppBar(
        actions: [
          BlocBuilder&lt;ThemeBloc, ThemeData&gt;(
            builder: (context, themeData) {
              <span class="hljs-keyword">return</span> CupertinoSwitch(
                  value: themeData == ThemeData.dark(),
                  <span class="hljs-attr">onChanged</span>: (bool val) {
                    BlocProvider.of&lt;ThemeBloc&gt;(context).add(ThemeSwitchEvent());
                  });
            },
          ),
        ],
      ),
      <span class="hljs-attr">body</span>: <span class="hljs-keyword">const</span> Center(child: Text(<span class="hljs-string">"Theme changing app"</span>)),
    );
  }
}
</code></pre><p>The code up to here is fine and we need to give a final touch to the code. If we run the above code we'll run into an exception of Provider not found or something. This is because we've not provided <code>ThemeBloc</code> to our App i.e. we need to provide our app with ThemeBloc above the place in widget tree where it is referenced.</p>
<p>Now,
Inside <code>runApp</code> method where you're calling MyApp() i.e. the root of your app where you've declared <code>MaterialApp</code>, you need to wrap your MyApp() like this:</p>
<pre><code>  BlocProvider(
      create: <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> ThemeBloc()
      <span class="hljs-attr">child</span>: <span class="hljs-keyword">const</span> MyApp(),
    )
</code></pre><p>If we do this, our app will run fine. Theme will also switch and the value is also set in shared preferences. Now, set the theme to dark and restart the app once, you'll see the theme is light even though we set the theme to dark and also set the value in shared preferences. This is because we didn't call <code>InitialThemeSetEvent</code> initially while our app's starting which led to Light theme by default as we kept light theme as default in theme bloc state. Now to call this, Update the above piece of code like this:</p>
<pre><code>  BlocProvider(
      create: <span class="hljs-function">(<span class="hljs-params">context</span>) =&gt;</span> ThemeBloc()..add(InitialThemeSetEvent())
      <span class="hljs-attr">child</span>: <span class="hljs-keyword">const</span> MyApp(),
    )
</code></pre><p>This'll provide theme bloc to the app and also call <code>InitialThemeSetEvent</code> simultaneously. Now, We're done. </p>
<p>The full source code is at: https://github.com/ankeet7x/theme_switch_using_bloc</p>
]]></content:encoded></item><item><title><![CDATA[Extension methods in Dart]]></title><description><![CDATA[Let's consider a dynamic list with few elements. 
List myList = ["mango", "apple", "guava"]; 
Let's consider you need to print the item at a specific index. For that index, we could do:

It simply prints mango in the console.
Now, Let's consider ther...]]></description><link>https://tejbikram.com.np/extension-methods-in-dart</link><guid isPermaLink="true">https://tejbikram.com.np/extension-methods-in-dart</guid><category><![CDATA[Dart]]></category><category><![CDATA[Flutter]]></category><dc:creator><![CDATA[Ankeet Karki]]></dc:creator><pubDate>Tue, 22 Mar 2022 19:12:05 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1647973156665/gAymR1YnI.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Let's consider a dynamic list with few elements. </p>
<p><code>List myList = ["mango", "apple", "guava"];</code> </p>
<p>Let's consider you need to print the item at a specific index. For that index, we could do:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647973156665/gAymR1YnI.png" alt="carbon (1).png" /></p>
<p>It simply prints <code>mango</code> in the console.</p>
<p>Now, Let's consider there existed a scenario when you need to print the item at any index including the index that might not be available in the list. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647973419014/DK7Yy16Jt.png" alt="carbon (2).png" /></p>
<p>In the above list, item doesn't exist at index 3, so if we print item at index 3, we should get <code>null</code> in the console as there exists nothing at <code>myList[3]</code>. </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647973692188/mj4wjiDNa.jpg" alt="illegal.jpg" /></p>
<p><code>Uncaught Error: RangeError (index): Index out of range: index should be less than 3: 3</code>. This error appeared in the console as we tried to access the item at index which doesn't exist. This means that we couldn't access the index that doesn't exist expecting it to print null in console. What if we want to print <code>null</code> if the item at index doesn't exist ? </p>
<p>We could do this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647974163491/RKf8JjKls.png" alt="carbon (3).png" /></p>
<p>This code works perfectly fine. What if we want to reuse this code ? It isn't a good idea to hard-code this piece of code everywhere. What we could do is create a function that returns item if it exists or null.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647974519809/9IDJUfHfm.png" alt="carbon (4).png" /></p>
<p>Nice, The program is running as we expected it to. Let's assume, We need to do this multiple times with multiple lists. In the above piece of code, We passed the index and the list to the function to do the operation but should we be passing the list everywhere ? What if we don't want to pass the list ?</p>
<p>That's where extension method comes in. According to extension method definition in Dart documentation, Extension methods, introduced in Dart 2.7, are a way to add functionality to existing libraries. They can be defined as:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647976111629/pvpI2E1SA.png" alt="carbon (7).png" /></p>
<p>Here, we need to add functionality to the list i.e. we need to print item at index or null. Since List is of type Iterable, we can create an extension on Iterables.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647975288336/nftUijePZ.png" alt="carbon (5).png" /></p>
<p>Now, the question "How to implement this ?" arises. Well, It's easy.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1647975659494/JpGSfw2qi.png" alt="carbon (6).png" /></p>
<p>After clicking dot after a specific list, The suggestion of <code>itemAtIndexOrNull</code> automatically shows up and we pass the required index and we're done.</p>
<p>The complete source code is:</p>
<p><code>extension ItemAtIndexOrNull&lt;T&gt; on Iterable&lt;T&gt; {</code> <br />
 <code>itemAtIndexOrNull(int index) {</code><br />
  <code>if (length &gt;= index + 1) {</code><br />
   <code>return elementAt(index);</code><br />
  <code>} else {</code><br />
   <code>return null;</code><br />
   }<br />
  }<br />
 }</p>
]]></content:encoded></item></channel></rss>