<?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: ibenge Uforo</title>
    <description>The latest articles on DEV Community by ibenge Uforo (@ibengeu).</description>
    <link>https://dev.to/ibengeu</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F493418%2Fc36e1c04-99d4-47a6-b97f-ea3fb5faab04.jpg</url>
      <title>DEV Community: ibenge Uforo</title>
      <link>https://dev.to/ibengeu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ibengeu"/>
    <language>en</language>
    <item>
      <title>How to Build Apps with AI: From Idea to API (Or X)</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sat, 26 Sep 2026 22:52:46 +0000</pubDate>
      <link>https://dev.to/ibengeu/how-to-build-apps-with-ai-from-idea-to-api-or-x-25jo</link>
      <guid>https://dev.to/ibengeu/how-to-build-apps-with-ai-from-idea-to-api-or-x-25jo</guid>
      <description>&lt;p&gt;Can AI help you build useful apps without settling for slop? This guide shows a human-led workflow for taking a product idea through requirements, feature-level implementation, API design, and verification. I use Orbit, a Slack-style team chat demo, as a case study. You can apply the process to your own product, whether you write code or are still shaping the idea.&lt;/p&gt;

&lt;p&gt;My first prompt was simple: “I want to build a Slack clone.” That sentence named a product category. It did not say who the product was for, what the first version had to do, what “done” meant, or which parts could be simulated.&lt;/p&gt;

&lt;p&gt;On social media, I often see two absolute claims: AI only builds “slop,” and AI cannot help create applications that reach production. Both claims miss the role of the people building the product. AI can help create useful software when people set the scope, review the changes, test the behavior, and own the release decision. AI-generated code cannot certify itself as production-ready.&lt;/p&gt;

&lt;p&gt;Orbit is a demo, not a production application. It has no sign-in, uses one shared public demo owner, and loses stored data when its process restarts. I will show what the AI-assisted workflow produced and what still needs verification before a production release. The prompt examples are teaching examples, not transcripts of the original conversations.&lt;/p&gt;

&lt;h2&gt;
  
  
  In this guide
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why AI output can be useful&lt;/li&gt;
&lt;li&gt;Orbit, the running example&lt;/li&gt;
&lt;li&gt;Turn the idea into requirements&lt;/li&gt;
&lt;li&gt;Build and review features&lt;/li&gt;
&lt;li&gt;Derive an API from accepted behavior&lt;/li&gt;
&lt;li&gt;What production readiness requires&lt;/li&gt;
&lt;li&gt;Apply the workflow to your product&lt;/li&gt;
&lt;li&gt;Further reading&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why AI output can be useful
&lt;/h2&gt;

&lt;p&gt;“Slop” is a fair description of output that looks complete but does not meet the user’s needs. A vague request gives an AI room to guess. If no one checks those guesses against real requirements, the result can look polished while behaving like the wrong product.&lt;/p&gt;

&lt;p&gt;The process for Orbit added checks at each handoff. ChatGPT helped expose missing decisions. Claude organized the decisions in a PRD and feature specs. Grok Build implemented bounded changes. I reviewed the UI, revised the requirements, and asked for an API audit only after the UI behavior was accepted. Feature acceptance criteria and tests made some results observable.&lt;/p&gt;

&lt;p&gt;That work is evidence that AI can contribute to product planning, interface work, API design, and implementation. It does not prove that Orbit is production-ready. The current demo has no sign-in, shared demo data, and process-scoped persistence. The last implementation notes report focused API and compose tests passing, but also note broader baseline failures and a blocked browser journey. The sections below describe both the work and its limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Orbit, the running example
&lt;/h2&gt;

&lt;p&gt;The screenshots follow a new visitor from the welcome screen to a channel, a thread, and a direct message.&lt;/p&gt;

&lt;p&gt;The welcome screen tells visitors that they share demo data. There is no sign-in. Do not enter private messages. Calls are simulated; they do not carry live audio or video.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fex5qdlwshypjk8j77mnx.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fex5qdlwshypjk8j77mnx.jpg" alt="Orbit welcome screen with a Continue as Alex Morgan action and a shared demo data notice." width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The welcome screen explains the shared demo before a visitor enters.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The seeded workspace lets a reviewer see a populated channel at once.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fue7q55n5ob8fjjcdl1k0.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fue7q55n5ob8fjjcdl1k0.jpg" alt="Orbit open to the #design channel, with messages and the workspace sidebar visible." width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The channel shows the navigation, conversation, and composer in one view.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The thread pane keeps replies beside the message that started them.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhj1m0p73kz6vrfhklp09.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fhj1m0p73kz6vrfhklp09.jpg" alt="Orbit's #design channel with a message thread open in the right pane." width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A thread is a separate conversation path inside the channel.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Direct messages use the same basic layout with a different recipient and history.&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5oio9xpoizxlpr9ebbr6.jpg" 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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F5oio9xpoizxlpr9ebbr6.jpg" alt="Orbit direct message conversation with Priya Shah." width="800" height="430"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A direct message has its own conversation history.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;These screens helped me judge the product's direction. They did not prove that every control behaved as required. I used the feature PRDs and acceptance criteria to review behavior.&lt;/p&gt;

&lt;h2&gt;
  
  
  Turn the idea into requirements before asking for code
&lt;/h2&gt;

&lt;p&gt;“Build a Slack clone” leaves many decisions open. Does the first version need accounts, real-time messages, calls, file uploads, mobile navigation, or search across every message?&lt;/p&gt;

&lt;p&gt;If a model answers those questions by guessing, it can build a polished interface for the wrong product. I used ChatGPT to make the missing decisions visible before I asked Claude to write the PRD.&lt;/p&gt;

&lt;p&gt;For your own product, replace the chat-specific questions with the users, tasks, data, and risks that matter in your domain. Keep the same method: ask the AI to expose unknowns before it writes a specification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 1: clarify the idea
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;I want to build a Slack-style team chat app.

Help me clarify the idea before you write a build prompt.
Ask questions about:
- who will use the app and what they need to do;
- the smallest useful first version;
- workspaces, channels, direct messages, threads, and search;
- accounts, data ownership, persistence, and real-time behavior;
- files, calls, mobile use, and accessibility;
- security, edge cases, and features that are out of scope.

Separate confirmed facts, assumptions, recommendations, and open questions.
Do not turn an unanswered question into a requirement.
Do not write code.
When the important questions are answered, write a structured brief I can
give to another assistant to draft a PRD.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The key instruction is to separate what I decided from what the model suggested. If the answer says “accounts are required” but I never chose an account system, that is an assumption to review, not a requirement to pass along.&lt;/p&gt;

&lt;p&gt;For a non-technical builder, describe the user and the problem in everyday language. For a technical builder, add the stack, integrations, data boundaries, and deployment constraints. Either way, ask the model to list unanswered questions instead of filling them in.&lt;/p&gt;

&lt;h3&gt;
  
  
  What BRD, PRD, and SRS mean
&lt;/h3&gt;

&lt;p&gt;The document names vary between companies. Teams also combine them. These are common meanings:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;BRD&lt;/strong&gt;, or Business Requirements Document, describes the business problem, stakeholders, expected outcomes, constraints, and success measures.&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;PRD&lt;/strong&gt;, or Product Requirements Document, describes users, product outcomes, workflows, feature priorities, and acceptance criteria.&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;SRS&lt;/strong&gt;, or Software Requirements Specification, describes testable software requirements, interfaces, constraints, and verification details.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The terms are related, but they do not mean the same thing. An SRS is a software requirements specification, not a “software specification requirement.” Formal standards use their own artifact names. &lt;a href="https://www.iso.org/obp/ui?_escaped_fragment_=iso%3Astd%3Aiso-iec-ieee%3A29148%3Aed-2%3Av1%3Aen" rel="noopener noreferrer"&gt;ISO/IEC/IEEE 29148&lt;/a&gt; describes requirements engineering across the system and software lifecycle, including business and software requirements specifications.&lt;/p&gt;

&lt;p&gt;For Orbit, Claude drafted the product requirements document, and we later created eight feature PRDs. We did not create separate BRD or SRS documents for this project. The feature PRDs and API contract captured the detail we used to build and review the app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 2: ask Claude for the PRD
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;Use the brief below to draft a Product Requirements Document for Orbit.

Include:
1. product problem, users, goals, and success measures;
2. priority user journeys;
3. functional requirements with testable acceptance criteria;
4. non-functional requirements for security, privacy, accessibility,
   responsive behavior, and performance;
5. data and integration needs;
6. non-goals, dependencies, risks, and open questions.

For every requirement, mark its source as confirmed, assumed, or proposed.
Do not invent business decisions. Put unresolved choices in an open-questions
section. Use plain language. Do not write code.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A PRD gives the people building the product one description of the user, the goal, and the expected behavior. It also gives the AI a boundary. “Build Slack” is not a boundary.&lt;/p&gt;

&lt;h2&gt;
  
  
  Build the first UI, then break the work into features
&lt;/h2&gt;

&lt;p&gt;Once Claude drafted the PRD, I passed it to Grok Build. The first design looked close to what I had in mind. That was a useful checkpoint. It was not a reason to assume that every behavior had been defined.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 3: give Grok Build the approved scope
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;Read the attached Orbit PRD and the existing project instructions.
First summarize the user, the first-release scope, and the acceptance criteria.
List conflicts and unanswered questions before changing the app.

Build the interface and behavior described in the approved scope.
Keep simulated behavior visibly separate from real persistence or services.
Do not add features because they are common in Slack.
After the change, report what works, what is simulated, what is incomplete,
and which acceptance criteria you could not verify.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The line about features common in Slack prevents scope creep. A clone brief does not automatically include every feature in the original product.&lt;/p&gt;

&lt;p&gt;When the first interface looked right, I returned to Claude and asked: “For this application, list out the features.” I turned that list into separate feature PRDs. Then I fed those documents to Grok Build one at a time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 4: ask for feature-level PRDs
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;Break the approved Orbit PRD into feature-level PRDs.

For each feature, include:
- user problem and user story;
- in-scope behavior and explicit non-goals;
- normal flow, edge cases, and empty/error states;
- data and permission rules;
- dependencies on other features;
- measurable acceptance criteria.

Keep accessibility and responsive requirements explicit.
Link each feature to the parent PRD requirement.
Flag overlap or conflict. Do not silently resolve it.
Separate the first release from later work.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Each feature needs a clear boundary. For example, “make channel switching smooth” is hard to verify. “When a user selects a channel, update the header, messages, composer placeholder, draft, and active sidebar item together” describes a visible result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 5: implement one feature at a time
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;Implement only the attached feature PRD: [feature name].

Before editing, summarize its acceptance criteria and identify the relevant
existing UI and tests. Ask about any conflict with the parent PRD instead of
guessing. Keep unrelated features unchanged.

After editing, report each acceptance criterion as verified, not verified,
or blocked. Show the behavior change and remaining gaps.
Do not claim that a simulated feature uses a real service.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I checked each revision against the accepted requirements before moving to the next feature. That review caught differences between a screen that looked right and a behavior that was actually specified.&lt;/p&gt;

&lt;h2&gt;
  
  
  Review the eight feature PRDs
&lt;/h2&gt;

&lt;p&gt;The first UI pass had eight feature-level PRDs. They describe UI behavior with local state and no backend. The calls PRD describes simulated calls and excludes WebRTC, signaling, and a media server. It refers to a separate future calls spec. The linked Gist contains only these eight feature PRDs. It does not contain the master product PRD, the later API specification, or the future calls spec.&lt;/p&gt;

&lt;p&gt;I extracted the eight Markdown PRDs and published them as individual files in a &lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11" rel="noopener noreferrer"&gt;public GitHub Gist&lt;/a&gt;. Select a title below to read the full PRD:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature PRD&lt;/th&gt;
&lt;th&gt;What it specifies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-01-layout-md" rel="noopener noreferrer"&gt;Layout&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Workspace rail, navigation sidebar, conversation pane, and thread pane.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-02-conversation-experience-md" rel="noopener noreferrer"&gt;Conversation experience&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Message rendering, grouping, reactions, threads, and message actions.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-03-composer-md" rel="noopener noreferrer"&gt;Composer&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Multiline input, sending, formatting controls, attachments, and per-conversation drafts.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-04-navigation-search-md" rel="noopener noreferrer"&gt;Navigation and search&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Channel and DM switching, search, Activity, Later, and menus.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-05-calls-md" rel="noopener noreferrer"&gt;Calls&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Simulated personal and group call flows, call states, and call history messages.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-06-seed-data-md" rel="noopener noreferrer"&gt;Sample content&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Seeded channels, DMs, threads, reactions, mentions, and work conversations.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-07-responsive-md" rel="noopener noreferrer"&gt;Responsive behavior&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Desktop, medium, and mobile navigation and layout rules.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://gist.github.com/ibengeu/709d707fb3749f3e647640277cd73c11#file-orbit-prd-08-accessibility-md" rel="noopener noreferrer"&gt;Accessibility&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;Semantic structure, keyboard use, visible focus, contrast, and edge cases.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The feature PRDs turn a product goal into work a designer or developer can review. Their acceptance criteria describe outcomes, not just appearance. The responsive spec, for example, says that mobile should show one primary pane at a time and keep the composer reachable when the keyboard is open.&lt;/p&gt;

&lt;h2&gt;
  
  
  After the UI review, derive the API from actual behavior
&lt;/h2&gt;

&lt;p&gt;The eight PRDs above describe the initial UI scope. After I was comfortable with the interface and its revisions, I asked ChatGPT to help draft a prompt for a new task: audit what the platform actually did and derive the REST API from those behaviors.&lt;/p&gt;

&lt;p&gt;This order matters. The API review started from accepted screens, feature specs, and user actions. It did not start from a list of endpoints or a guess about what Slack might need.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt 6: audit the UI and propose an API contract
&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;The Orbit interface and feature PRDs have been reviewed and accepted.
Audit the provided screens, PRDs, interaction list, and existing project behavior.
Use only these sources. Do not add features because a competitor has them.

First, inventory each user-visible action and the data it reads or changes.
Group related actions by resource. Do not create one endpoint for every button.
Separate browser-only state from data that must persist on the server.

For each proposed operation, document:
- user outcome and resource;
- HTTP method and versioned URI;
- request and response shape;
- success and error status codes;
- authentication, ownership, and authorization rules;
- validation, size limits, and safe failure behavior;
- idempotency or concurrency needs;
- pagination and ordering rules;
- one observable API behavior test.

Design a resource-oriented HTTP API using standard method semantics.
Use RFC 9457 Problem Details for API errors with the
application/problem+json media type.
Describe the contract in OpenAPI.
Before implementation, list assumptions, conflicts, and questions.
Do not write application code.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I reviewed the proposed operations before implementation. The API contract records the paths, methods, inputs, outputs, and failure cases that the UI and server agree to support. OpenAPI gives those details a machine-readable format for documentation and contract checks.&lt;/p&gt;

&lt;h3&gt;
  
  
  RESTful and resource-oriented APIs
&lt;/h3&gt;

&lt;p&gt;REST means Representational State Transfer. It is an architectural style for networked systems. Roy Fielding's description includes constraints such as a uniform interface, stateless interactions, cacheable responses, a layered system, and hypermedia. &lt;a href="https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" rel="noopener noreferrer"&gt;Fielding's dissertation explains the REST constraints&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A resource-oriented API organizes its paths around the things the product manages. Orbit has workspaces, conversations, messages, reactions, saved messages, and calls. Clients use standard HTTP methods to read or change representations of those resources.&lt;/p&gt;

&lt;p&gt;For example, &lt;code&gt;GET&lt;/code&gt; reads a representation, &lt;code&gt;POST&lt;/code&gt; submits data for processing or creates a resource in a collection, and &lt;code&gt;DELETE&lt;/code&gt; requests removal of a resource. &lt;code&gt;PATCH&lt;/code&gt; applies partial changes. &lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html" rel="noopener noreferrer"&gt;RFC 9110 defines HTTP method semantics&lt;/a&gt;, and &lt;a href="https://www.rfc-editor.org/rfc/rfc5789.html" rel="noopener noreferrer"&gt;RFC 5789 defines HTTP PATCH&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Teams often use “RESTful” to describe APIs with resource paths and standard HTTP semantics. Those choices alone do not prove that an API follows every REST constraint. Orbit uses a resource-oriented REST API design. This article does not claim full hypermedia-driven REST conformance.&lt;/p&gt;

&lt;p&gt;Here are actual operations from the Orbit API contract:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;User behavior&lt;/th&gt;
&lt;th&gt;HTTP operation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;List workspaces&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /api/v1/workspaces&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Create a workspace&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/workspaces&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;List a workspace's channels and DMs&lt;/td&gt;
&lt;td&gt;&lt;code&gt;GET /api/v1/workspaces/{workspaceId}/conversations&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Send a message or thread reply&lt;/td&gt;
&lt;td&gt;&lt;code&gt;POST /api/v1/conversations/{conversationId}/messages&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Edit or restore the caller's message&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PATCH /api/v1/messages/{messageId}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Add or remove a reaction&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PUT&lt;/code&gt; or &lt;code&gt;DELETE /api/v1/messages/{messageId}/reactions/{emoji}&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;These paths name resources, such as &lt;code&gt;/messages&lt;/code&gt;, instead of actions, such as &lt;code&gt;/sendMessage&lt;/code&gt;. That gives developers and clients a predictable contract to read and test. It does not provide authorization by itself. The server must still validate every request and enforce ownership.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why use RFC 9457 Problem Details
&lt;/h3&gt;

&lt;p&gt;An HTTP status code gives the general result. A &lt;code&gt;400 Bad Request&lt;/code&gt; response says that the request is invalid, but the client may need more detail to explain the problem or let the user fix it.&lt;/p&gt;

&lt;p&gt;RFC 9457 defines a common, machine-readable format for those details. The response uses the &lt;code&gt;application/problem+json&lt;/code&gt; media type. This gives API clients one shape for errors instead of a different format on each route. &lt;a href="https://www.rfc-editor.org/rfc/rfc9457.html" rel="noopener noreferrer"&gt;RFC 9457 defines Problem Details for HTTP APIs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, an invalid message-page token could return:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{
  "type": "https://api.orbit.example/problems/invalid-page-token",
  "title": "Invalid page token",
  "status": 400,
  "detail": "The page token is malformed or expired.",
  "instance": "/api/v1/conversations/c_123/messages"
}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The HTTP response carries the actual status code. The JSON body gives the client a stable problem type and a safe explanation. Do not put stack traces, secrets, or private message content in the error detail.&lt;/p&gt;

&lt;h2&gt;
  
  
  Follow one feature from idea to test
&lt;/h2&gt;

&lt;p&gt;Consider sending a message to a channel. This single behavior connects the product, UI, API, security rules, and tests:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Product goal:&lt;/strong&gt; A teammate can send a message in the conversation they selected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;UI requirement:&lt;/strong&gt; The composer names the selected channel or person. After a successful send, the message appears in that conversation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API resource:&lt;/strong&gt; The message belongs to a conversation, so the client submits it to &lt;code&gt;POST /api/v1/conversations/{conversationId}/messages&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server rules:&lt;/strong&gt; Validate the message body and conversation. When authentication is enabled, derive the owner from the verified session. Do not trust an owner ID sent by the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Error behavior:&lt;/strong&gt; If the request is invalid, return the right HTTP status and a Problem Details response. If the send fails, keep the unsent draft available in the browser.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavior checks:&lt;/strong&gt; Verify that a successful send returns the saved message and that a later read returns it. Verify that a different owner cannot read or change the message when authenticated mode is active.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The original Composer PRD described UI-only local state. The later API work changed that boundary: sent messages became server-owned, while unsent drafts stayed in the browser. The PRD and API contract describe different stages of the project.&lt;/p&gt;

&lt;h2&gt;
  
  
  The code history shows how the scope grew
&lt;/h2&gt;

&lt;p&gt;Four commits record decisions after the first interface:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Commit&lt;/th&gt;
&lt;th&gt;What changed&lt;/th&gt;
&lt;th&gt;Why it mattered&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;“Finish workspace switching and the broken message actions.”&lt;/td&gt;
&lt;td&gt;Workspace creation and switching, workspace-scoped search, safe links, and message actions became usable.&lt;/td&gt;
&lt;td&gt;The main user journey needed to work as one product.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“feat(orbit): persist workspace data through API.”&lt;/td&gt;
&lt;td&gt;Shared actions moved behind versioned REST routes and SQL-backed tables. The API contract and action map were documented.&lt;/td&gt;
&lt;td&gt;The UI needed a consistent place to read and write saved data.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“chore: clarify Orbit interface copy.”&lt;/td&gt;
&lt;td&gt;The interface text became clearer.&lt;/td&gt;
&lt;td&gt;Labels affect what users expect each control to do.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;“Optimize Orbit runtime and pagination.”&lt;/td&gt;
&lt;td&gt;Repeated scans were reduced, message details were fetched in batches, and stable keyset pagination was added while offset cursors remained supported.&lt;/td&gt;
&lt;td&gt;Long message histories need stable pages and bounded work.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The API build added a server boundary:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;React interface → versioned REST API → validation and ownership checks → SQL&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The browser keeps view state and unsent drafts. The API stores shared product data. When authentication is enabled, the server scopes reads and writes to the verified owner.&lt;/p&gt;

&lt;p&gt;Orbit's current demo has no sign-in. All visitors use one shared public demo owner. Its local database survives page reloads while the process runs, but a process restart clears that data. Production identity and durable storage have not been verified. Do not use the demo for private messages.&lt;/p&gt;

&lt;p&gt;The performance commit reduced repeated scans and batched reads. The project has no benchmark baseline, so the commit does not prove a measured speedup.&lt;/p&gt;

&lt;p&gt;The implementation notes for the last code phase report 21 focused API and compose tests passing and a passing TypeScript check. The broader suite still had baseline failures. A browser journey also could not bind its server in the default sandbox. Those results do not support the claim that every check passed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What production readiness still requires
&lt;/h2&gt;

&lt;p&gt;AI does not change the release standard. A team still needs evidence that the application is safe, reliable, and operable in its target environment. A polished screen, a successful build, or a group of passing tests cannot establish that on its own.&lt;/p&gt;

&lt;p&gt;Before a production release, review at least these areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity and access:&lt;/strong&gt; authenticate users, enforce authorization on the server, and test that one user cannot read or change another user's data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Data durability:&lt;/strong&gt; verify production database configuration, migrations, backups, recovery, and retention. Orbit's current demo data is cleared when its process restarts.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Security and privacy:&lt;/strong&gt; validate inputs, protect secrets, return safe errors, set resource limits, and check logs for sensitive data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Behavior and failure tests:&lt;/strong&gt; test user-visible outcomes, invalid requests, access boundaries, and service failures in the target deployment. Resolve or explain failures in the broader suite.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operations:&lt;/strong&gt; verify monitoring, alerts, capacity, recovery, and a rollback path. Measure performance before claiming an optimization improved it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Usability:&lt;/strong&gt; check accessibility, responsive behavior, and real user journeys on supported devices.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Orbit does not pass this full release review today. It has no sign-in, uses a shared public demo owner, and has process-scoped persistence. The project notes also record broader test failures, a browser journey that could not run in its environment, and no performance baseline. Those are known limits to address before production use.&lt;/p&gt;

&lt;p&gt;This is how AI-assisted work can fit into production development: AI helps produce plans, code, and test ideas; the team verifies the system, closes release gaps, and owns the decision to ship. NIST's &lt;a href="https://csrc.nist.gov/Projects/ssdf" rel="noopener noreferrer"&gt;Secure Software Development Framework&lt;/a&gt; and OWASP's &lt;a href="https://owasp.org/projects/asvs?tab=main" rel="noopener noreferrer"&gt;Application Security Verification Standard&lt;/a&gt; provide deeper guidance for that work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apply the workflow to your own product
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Write one sentence that names the user and the problem.&lt;/li&gt;
&lt;li&gt;Ask an AI assistant to find missing decisions. Keep confirmed facts, assumptions, suggestions, and open questions separate.&lt;/li&gt;
&lt;li&gt;Ask for a PRD. Review users, outcomes, user journeys, non-goals, and acceptance criteria before building.&lt;/li&gt;
&lt;li&gt;Build a first interface from the approved scope. Compare it with the user journeys and revise the requirements when the prototype exposes gaps.&lt;/li&gt;
&lt;li&gt;Break the PRD into feature PRDs. Link each feature to its parent requirement and give each one observable acceptance criteria.&lt;/li&gt;
&lt;li&gt;Feed one feature to the build assistant at a time. Review the result before moving to the next feature.&lt;/li&gt;
&lt;li&gt;Once the UI behavior is accepted, inventory its actions and data. Map server-persisted behavior to resources, HTTP methods, paths, schemas, ownership rules, errors, and tests.&lt;/li&gt;
&lt;li&gt;Describe the API contract in OpenAPI. Use consistent HTTP status codes and RFC 9457 Problem Details for API errors.&lt;/li&gt;
&lt;li&gt;Implement one vertical slice. Check the public behavior, inspect the change, record gaps, and update the requirements.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The documents do not remove judgment from the process. They give the team something specific to review each time the AI makes a change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources for further reading
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prompt design&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.openai.com/api/docs/guides/prompt-engineering" rel="noopener noreferrer"&gt;OpenAI's prompt engineering guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/overview" rel="noopener noreferrer"&gt;Anthropic's prompt engineering overview&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Product and software requirements&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.iso.org/obp/ui?_escaped_fragment_=iso%3Astd%3Aiso-iec-ieee%3A29148%3Aed-2%3Av1%3Aen" rel="noopener noreferrer"&gt;ISO/IEC/IEEE 29148:2018&lt;/a&gt;, requirements engineering across system and software lifecycles&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/software/confluence/templates/product-requirements" rel="noopener noreferrer"&gt;Atlassian's product requirements template&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.atlassian.com/software/confluence/resources/guides/how-to/business-requirements" rel="noopener noreferrer"&gt;Atlassian's business requirements guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;HTTP APIs and errors&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm" rel="noopener noreferrer"&gt;Roy Fielding's REST dissertation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9110.html" rel="noopener noreferrer"&gt;RFC 9110: HTTP Semantics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc5789.html" rel="noopener noreferrer"&gt;RFC 5789: PATCH Method for HTTP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spec.openapis.org/oas/" rel="noopener noreferrer"&gt;OpenAPI Specification&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9457.html" rel="noopener noreferrer"&gt;RFC 9457: Problem Details for HTTP APIs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Accessibility&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/wcag/" rel="noopener noreferrer"&gt;W3C Web Content Accessibility Guidelines (WCAG) 2.2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The takeaway
&lt;/h2&gt;

&lt;p&gt;I started with one broad idea and used AI across product clarification, PRDs, interface work, feature revisions, and API design. The useful skill was making each decision explicit, reviewing the result, and recording what remained unverified.&lt;/p&gt;

&lt;p&gt;That workflow applies beyond team chat. Start with the people and problem behind your product. Ask AI to expose uncertainty. Approve the requirements. Build and review one feature at a time. Derive the API from the behavior the product needs. Then check the evidence required for your own release.&lt;/p&gt;

&lt;p&gt;Orbit shows that AI can contribute to serious application work under human direction. It also shows why a prototype and a production release need different evidence.&lt;/p&gt;

&lt;p&gt;Link to UI - &lt;a href="https://orbit-indol-alpha.vercel.app/" rel="noopener noreferrer"&gt;https://orbit-indol-alpha.vercel.app/&lt;/a&gt;&lt;br&gt;
Link to Repo - &lt;a href="https://github.com/ibengeu/orbit.git" rel="noopener noreferrer"&gt;https://github.com/ibengeu/orbit.git&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>react</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Entry-9: Cache Control, Long story short.</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sat, 13 Apr 2024 19:15:24 +0000</pubDate>
      <link>https://dev.to/ibengeu/cache-control-jfj</link>
      <guid>https://dev.to/ibengeu/cache-control-jfj</guid>
      <description>&lt;p&gt;HTTP caching involves storing response messages locally to reduce response time and network bandwidth consumption for future equivalent requests. An HTTP "cache" acts as a local store managed by a subsystem that controls the storage, retrieval, and deletion of messages within it. By storing cacheable responses, this system optimizes performance by minimizing the need to fetch resources repeatedly from the origin server (source: &lt;a href="https://www.rfc-editor.org/rfc/rfc9111#name-introduction" rel="noopener noreferrer"&gt;RFC 9111&lt;/a&gt;) and reduce the server load.&lt;/p&gt;

&lt;p&gt;To implement effective HTTP caching, it's essential to include cache control headers in responses. These headers provide directives to clients and intermediaries(Or Proxies eg. CDNs), guiding them on how to cache responses. Here's a breakdown of some crucial cache control options and directives:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Age&lt;/strong&gt;: This directive indicates the age of the response since it was generated, aiding in determining freshness or staleness.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;max-age&lt;/strong&gt;: Specifies the maximum time in seconds that a response can be considered fresh, enhancing caching efficiency.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;must-revalidate&lt;/strong&gt;: Mandates revalidation of a cached response with the origin server before use, ensuring clients receive updated content.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;private or public&lt;/strong&gt;: Determine whether a response can be cached by private client caches or shared caches, providing flexibility in caching strategies.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As such, there are other important directives which can be used. we can refer to the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#vocabulary" rel="noopener noreferrer"&gt;Mozilla Cache Control documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Additionally, using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/ETag" rel="noopener noreferrer"&gt;Etag&lt;/a&gt; property can signal to clients that a resource has not changed therefore returning with a 304 not modified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Scenarios
&lt;/h3&gt;

&lt;p&gt;Cache control headers find utility in various scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Order Details&lt;/strong&gt;: Setting cache control headers with a &lt;code&gt;max-age&lt;/code&gt; directive for order details allows caching for improved performance, especially considering the infrequent changes to this data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static Content&lt;/strong&gt;: Applying cache control headers to static content like images and stylesheets reduces server load and enhances page load times for subsequent visits. Implementing cache-busting techniques can further refine cache management for static assets.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public API Responses&lt;/strong&gt;: For frequently accessed public API responses, configuring cache control headers appropriately can alleviate server load and enhance response times.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A reason these examples are picked is due to the &lt;a href="https://www.rfc-editor.org/rfc/rfc9111#name-security-considerations" rel="noopener noreferrer"&gt;security considerations&lt;/a&gt; which one can be prone to and cannot be not to careful about hence, cache what you, your team or organization consider not sensitive information.&lt;/p&gt;

&lt;p&gt;Some ways these risk can be mitigated are by using&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CSRF Tokens&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Not storing the cache, and if some item eventually ends up in the cache setting the no store and max-age immediately marks it as stale.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;Cache-Control:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;no-store,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;max-age=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

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

&lt;h2&gt;
  
  
  &lt;strong&gt;Example Snippets&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;cache-control:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;max-age=&lt;/span&gt;&lt;span class="mi"&gt;3600&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;private,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;must-revalidate&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet instructs the consumer to cache the response for an hour using a private cache, ensuring revalidation with the server before the cached content can be reused after staleness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;(C#)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As I’m a csharp guy, In a C# environment, leveraging the &lt;strong&gt;ICache&lt;/strong&gt; or &lt;strong&gt;ResponseCacheAttribute&lt;/strong&gt; at the controller level helps with cache control. for Icache do see below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;client&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;readonly&lt;/span&gt; &lt;span class="n"&gt;ICache&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;ProductCatalogClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ICache&lt;/span&gt; &lt;span class="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseAddress&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productCatalogueBaseUrl&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="n"&gt;client&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&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="n"&gt;cache&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;cache&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;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;HttpResponseMessage&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;RequestProductFromProductCatalog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;productCatalogIds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;productsResource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"myProductResource"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;response&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="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productsResource&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;HttpResponseMessage&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="n"&gt;response&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productsResource&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nf"&gt;AddToCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;productsResource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&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="n"&gt;response&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;void&lt;/span&gt; &lt;span class="nf"&gt;AddToCache&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;HttpResponseMessage&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cacheHeader&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Headers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;h&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;h&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"cache-control"&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="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsNullOrEmpty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cacheHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="n"&gt;CacheControlHeaderValue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryParse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;cacheHeader&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;cacheControl&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
        &lt;span class="n"&gt;cacheControl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxAge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HasValue&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="n"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cacheControl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;MaxAge&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&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;Seems pretty straightforward ba?, if not here is an explanation.&lt;/p&gt;

&lt;p&gt;The main goal which is to make use of the cache response, so to achieve this we first check if there is any available cache for the product resource and return the response else, we fetch from the product catalog resource, checking if we are allowed to cache and then add.&lt;/p&gt;

&lt;p&gt;Some other ways we can do this is to make use of Redis or Valkey (Topic for another day) by the server and save/return cached responses from there!.&lt;/p&gt;

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

&lt;p&gt;So!,In essence, caching holds significant importance for business stakeholders by enhancing customer experience through quicker response times and aiding developers in supporting business operations. However, the efficiency of caching hinges on how it's implemented and with careful consideration of security implications. Thus, when implementing caching, it's vital to assess the benefits and drawbacks in alignment with specific business requirement and thought.&lt;/p&gt;

&lt;p&gt;Thanks for watching.&lt;/p&gt;

&lt;p&gt;Additional links and Resources&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://qwiet.ai/tackling-caching-issues-understanding-cache-control-for-security/" rel="noopener noreferrer"&gt;https://qwiet.ai/tackling-caching-issues-understanding-cache-control-for-security/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc9111#name-introduction" rel="noopener noreferrer"&gt;https://www.rfc-editor.org/rfc/rfc9111&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://securityintelligence.com/posts/data-security-defend-against-cache-poisoning/" rel="noopener noreferrer"&gt;https://securityintelligence.com/posts/data-security-defend-against-cache-poisoning/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Socials&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>csharp</category>
      <category>http</category>
      <category>cache</category>
    </item>
    <item>
      <title>Entry-8: PGP(Pretty Good Privacy) Encryption/Decryption c#</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sat, 11 Nov 2023 23:57:29 +0000</pubDate>
      <link>https://dev.to/ibengeu/pgp-encryptiondecryption-c-2ng4</link>
      <guid>https://dev.to/ibengeu/pgp-encryptiondecryption-c-2ng4</guid>
      <description>&lt;p&gt;One way or another, we would encounter a situation wherein we need to protect the privacy of data being shared over the internet or personal spaces.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Pretty_Good_Privacy" rel="noopener noreferrer"&gt;PGP&lt;/a&gt; (short for Pretty Good Privacy), created by &lt;a href="https://en.wikipedia.org/wiki/Phil_Zimmermann" rel="noopener noreferrer"&gt;Phillip Zimmerman&lt;/a&gt;, has been touted as one of the encryption mechanisms, even considered unbreakable by governments—yes, at least known by our mortal info(source: trust me).&lt;/p&gt;

&lt;p&gt;The decision to use PGP was driven by the limitations of asymmetric encryption, which had a size constraint on the data it could encrypt and other moving parts to sign or ensure the encrypted data was intended for the recipient (i.e., Web of trust). PGP, being asymmetric with a public and private key pair, provided the flexibility I needed.&lt;/p&gt;

&lt;p&gt;My initial research involved exploring examples from the book by D. Hook, &lt;a href="https://www.bouncycastle.org/fips-java/BCFipsIn100.pdf" rel="noopener noreferrer"&gt;Bouncy Castle FIPS Java&lt;/a&gt;, specifically focusing on AEAD (Authenticated Encryption with Associated Data) and AE (Authenticated Encryption). Additionally, I referred to &lt;a href="https://stackoverflow.com/questions/10999542/bouncy-castle-c-sharp-pgp-decryption-example" rel="noopener noreferrer"&gt;Stack Overflow discussions&lt;/a&gt; to address challenges, such as encountering an "invalid header" issue during decryption.&lt;/p&gt;

&lt;p&gt;So, in basic steps, to encrypt and decrypt an item in PGP, one could summarize as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Obtain the public and private key - This can be obtained from &lt;a href="https://pgpkeygen.com/" rel="noopener noreferrer"&gt;PGPGenerator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Encrypt and Decrypt.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Obtain the Public and Private key.
&lt;/h3&gt;

&lt;p&gt;After downloading the ascii-armoured file for the public and private key, which is the text-based representation of binary data (such as cryptographic keys) using ASCII characters. we would perform the following operations on it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open the specified PGP armored file (.asc) as a stream. This could be a text file as well, just ensure the content structure remains the same&lt;/li&gt;
&lt;li&gt;Create an ArmoredInputStream from the file stream which is used to read PGP armored data.&lt;/li&gt;
&lt;li&gt;Read the contents of the ArmoredInputStream into a byte array.&lt;/li&gt;
&lt;li&gt;Create a new stream from the byte array.&lt;/li&gt;
&lt;li&gt;Initialize a &lt;strong&gt;PgpPublicKeyRingBundle&lt;/strong&gt; with the byte stream which is a container holding a set of public and private key rings.&lt;/li&gt;
&lt;li&gt;Retrieve the key rings from the bundle.&lt;/li&gt;
&lt;li&gt;Extract the public key ring from the key rings which is a set of keys with associated metadata.&lt;/li&gt;
&lt;li&gt;Ensure that a public key ring is found in the specified key file.&lt;/li&gt;
&lt;li&gt;Extract the public keys from the public key ring.&lt;/li&gt;
&lt;li&gt;Return the first PGP public key from the extracted public keys.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Putting all these together, we would have.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Gets the public key from an pgp amoured file ie. asc&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;param name="publicKeyFilePath"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;exception cref="InvalidOperationException"&amp;gt;&amp;lt;/exception&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;PgpPublicKey&lt;/span&gt; &lt;span class="nf"&gt;GetPgpPubKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;publicKeyFilePath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;keyFileStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;OpenRead&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;publicKeyFilePath&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ArmoredInputStream&lt;/span&gt; &lt;span class="n"&gt;armoredInputStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyFileStream&lt;/span&gt;&lt;span class="p"&gt;))&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="c1"&gt;// Read the contents of the ArmoredInputStream into a byte array&lt;/span&gt;
                    &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;keyData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Streams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;armoredInputStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                    &lt;span class="c1"&gt;// Create a new stream from the byte array&lt;/span&gt;
                    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;keyDataStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="n"&gt;PgpPublicKeyRingBundle&lt;/span&gt; &lt;span class="n"&gt;publicKeyRingBundle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyDataStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                    &lt;span class="c1"&gt;// Assuming you want the first public key in the file&lt;/span&gt;
                    &lt;span class="n"&gt;PgpPublicKeyRing&lt;/span&gt; &lt;span class="n"&gt;publicKeyRing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;publicKeyRingBundle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetKeyRings&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;OfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PgpPublicKeyRing&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&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="n"&gt;publicKeyRing&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&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="n"&gt;publicKeyRing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetPublicKeys&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;OfType&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;PgpPublicKey&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;FirstOrDefault&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                    &lt;span class="p"&gt;}&lt;/span&gt;
                    &lt;span class="k"&gt;else&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="nf"&gt;InvalidOperationException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"No public key ring found in the specified key file."&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;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Error reading the key file: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;throw&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="n"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"IO error reading the key file: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                    &lt;span class="k"&gt;throw&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;p&gt;Retrieving the private key is a different process as we need to add in the passphrase used in signing the private key.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a file stream to read the specified PGP armored private key file.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;PgpSecretKeyRing&lt;/code&gt; to read the secret key ring from the file stream, decoding the armored data

&lt;ul&gt;
&lt;li&gt;Get the secret key from the secret key ring. In my case, I would be retrieving the first key.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Use the &lt;code&gt;ExtractPrivateKey&lt;/code&gt; method of &lt;code&gt;PgpSecretKey&lt;/code&gt; to obtain the private key, providing the passphrase as a character array&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Once more, putting this together.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// Gets the private key from a pgp amoured file ie. asc&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;param name="privateKeyFilePath"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;param name="passphrase"&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
        &lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="n"&gt;PgpPrivateKey&lt;/span&gt; &lt;span class="nf"&gt;GetPgpPrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;privateKeyFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;passphrase&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;PgpSecretKeyRing&lt;/span&gt; &lt;span class="n"&gt;secretKeyRing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;keyFileStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;FileStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;privateKeyFilePath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;FileMode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
                &lt;span class="p"&gt;{&lt;/span&gt;
                    &lt;span class="n"&gt;secretKeyRing&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PgpSecretKeyRing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpUtilities&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDecoderStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyFileStream&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
                &lt;span class="p"&gt;}&lt;/span&gt;

                &lt;span class="n"&gt;PgpSecretKey&lt;/span&gt; &lt;span class="n"&gt;secretKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secretKeyRing&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetSecretKey&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
                &lt;span class="n"&gt;PgpPrivateKey&lt;/span&gt; &lt;span class="n"&gt;privateKey&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;secretKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ExtractPrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;passphrase&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToCharArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;privateKey&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="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Handle exceptions, log errors, or take appropriate action.&lt;/span&gt;
                &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Error reading PGP private key from file: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;throw&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;Some issues encountered within this process &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invalid header exception  - this was resolved by first using pgp.utilities.getdecoderstream to handle the memory stream and pass it to the underlying method.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Resources for this section&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/65355150/read-ecc-private-key-pem-into-asymmetriccipherkeypair-c-sharp-bouncy-castle" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/65355150/read-ecc-private-key-pem-into-asymmetriccipherkeypair-c-sharp-bouncy-castle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/questions/10999542/bouncy-castle-c-sharp-pgp-decryption-example" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/10999542/bouncy-castle-c-sharp-pgp-decryption-example&lt;/a&gt; of which i got the idea to use PgpUtilities.GetDecoderStream(keyFileStream) for the pgp public key stream&lt;/li&gt;
&lt;li&gt;&lt;a href="https://stackoverflow.com/questions/10999542/bouncy-castle-c-sharp-pgp-decryption-example" rel="noopener noreferrer"&gt;https://stackoverflow.com/questions/10999542/bouncy-castle-c-sharp-pgp-decryption-example&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Encrypting
&lt;/h3&gt;

&lt;p&gt;In order to encrypt, we could follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a memory stream, which enables us to buffer the object while reading.&lt;/li&gt;
&lt;li&gt;Open a stream with the PgpLiteralDataGenerator, which writes the plain text data into a literal data packet.&lt;/li&gt;
&lt;li&gt;Initialize a PgpEncryptedDataGenerator, configured to use AES-256 as the symmetric key algorithm, enable integrity checking, and utilize a secure random number generator for cryptographic operations.&lt;/li&gt;
&lt;li&gt;Add the encryption type, which in my case is using a public key. At the time of writing, there are other methods such as using a passphrase.&lt;/li&gt;
&lt;li&gt;Write the encrypted data to your specified stream.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's enough theory, see what I mean below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// Encrypts the provided plaintext data using the specified PGP public key.&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="encryptionKey"&amp;gt;The PGP public key used for encryption.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="plainText"&amp;gt;The plaintext data to be encrypted.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;The encrypted data as a byte array.&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;EncryptDataWithPublicKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpPublicKey&lt;/span&gt; &lt;span class="n"&gt;encryptionKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Create a MemoryStream to store the encrypted data.&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemoryStream&lt;/span&gt; &lt;span class="n"&gt;encryptedStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Create a PgpLiteralDataGenerator to generate literal data packets in PGP.&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpLiteralDataGenerator&lt;/span&gt; &lt;span class="n"&gt;literalDataGenerator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PgpLiteralDataGenerator&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Open a stream with the PgpLiteralDataGenerator and write the plaintext data into a literal data packet.&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;literalDataStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;literalDataGenerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encryptedStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;PgpLiteralData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Binary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;PgpLiteralData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UtcNow&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;literalDataStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;plainText&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&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;// Create a MemoryStream to store the final result.&lt;/span&gt;
        &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemoryStream&lt;/span&gt; &lt;span class="n"&gt;resultStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Create a PgpEncryptedDataGenerator with the specified symmetric key algorithm, enabling integrity protection.&lt;/span&gt;
            &lt;span class="n"&gt;PgpEncryptedDataGenerator&lt;/span&gt; &lt;span class="n"&gt;encryptedDataGenerator&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PgpEncryptedDataGenerator&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;SymmetricKeyAlgorithmTag&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Aes256&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;SecureRandom&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

            &lt;span class="c1"&gt;// Add the encryption key to the generator.&lt;/span&gt;
            &lt;span class="n"&gt;encryptedDataGenerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encryptionKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

            &lt;span class="c1"&gt;// Open a stream with the encryptedDataGenerator and write the encrypted data into the result stream.&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;compressedOut&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encryptedDataGenerator&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resultStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encryptedStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;compressedOut&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encryptedStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;encryptedStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;

            &lt;span class="c1"&gt;// Return the encrypted data as a byte array.&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;resultStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&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;
  
  
  Decrypting.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We initialize a PgpObjectFactory to parse the PGP encrypted data.&lt;/li&gt;
&lt;li&gt;Get the first object from the factory, which bouncycastle expects to be a PgpEncryptedDataList.&lt;/li&gt;
&lt;li&gt;For situations where there are multiple recipients looping through &lt;strong&gt;PgpPublicKeyEncryptedData&lt;/strong&gt; gets us the public keyid used in encrypting the data and matches it with the keyid provided by the private key. enabling us correctly decrypt the data.&lt;/li&gt;
&lt;li&gt;The rest is history.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="c1"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// Decrypts PGP encrypted data using the provided private key and returns the decrypted bytes.&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="privateKey"&amp;gt;The PGP private key used for decryption.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;param name="encryptedB64String"&amp;gt;The base64-encoded PGP encrypted data.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;returns&amp;gt;The decrypted data as a byte array.&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;/// &amp;lt;exception cref="Exception"&amp;gt;Thrown in case of decryption failure or IO exceptions.&amp;lt;/exception&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="nf"&gt;DecryptDataWithPrivateKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpPrivateKey&lt;/span&gt; &lt;span class="n"&gt;privateKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;encryptedB64String&lt;/span&gt;&lt;span class="p"&gt;)&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="c1"&gt;// Convert the base64-encoded PGP encrypted data to a byte array&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;pgpEncryptedData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Convert&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;FromBase64String&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encryptedB64String&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a PgpObjectFactory for parsing the PGP encrypted data&lt;/span&gt;
    &lt;span class="n"&gt;PgpObjectFactory&lt;/span&gt; &lt;span class="n"&gt;pgpFact&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PgpObjectFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pgpEncryptedData&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Obtain the first object, which should be a PgpEncryptedDataList&lt;/span&gt;
    &lt;span class="n"&gt;PgpEncryptedDataList&lt;/span&gt; &lt;span class="n"&gt;encList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpEncryptedDataList&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;pgpFact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NextPgpObject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="c1"&gt;// Find the correct PgpPublicKeyEncryptedData using the provided private key&lt;/span&gt;
    &lt;span class="n"&gt;PgpPublicKeyEncryptedData&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;encData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpPublicKeyEncryptedData&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;encList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetEncryptedDataObjects&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="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KeyId&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="n"&gt;privateKey&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;KeyId&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;encData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&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;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encData&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="k"&gt;null&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="nf"&gt;PgpException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Provided private key not found in encrypted data."&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a decrypted stream&lt;/span&gt;
    &lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;clear&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;encData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetDataStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;privateKey&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Create a new MemoryStream to hold the decrypted data&lt;/span&gt;
    &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MemoryStream&lt;/span&gt; &lt;span class="n"&gt;decryptedStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;MemoryStream&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Read the decrypted data into the MemoryStream&lt;/span&gt;
        &lt;span class="n"&gt;Streams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;PipeAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clear&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;decryptedStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

        &lt;span class="c1"&gt;// Verify the integrity of the decrypted data&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;encData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Verify&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Create a PgpObjectFactory for parsing the decrypted literal data&lt;/span&gt;
            &lt;span class="n"&gt;PgpObjectFactory&lt;/span&gt; &lt;span class="n"&gt;litFact&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;PgpObjectFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;decryptedStream&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;

            &lt;span class="c1"&gt;// Obtain the literal data packet&lt;/span&gt;
            &lt;span class="n"&gt;PgpLiteralData&lt;/span&gt; &lt;span class="n"&gt;litData&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpLiteralData&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;litFact&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;NextPgpObject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

            &lt;span class="c1"&gt;// Read the actual data from the literal data input stream&lt;/span&gt;
            &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Stream&lt;/span&gt; &lt;span class="n"&gt;dataStream&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;litData&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;GetInputStream&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Streams&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ReadAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataStream&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&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;span class="k"&gt;else&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="nf"&gt;PgpException&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Modification check failed."&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="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;PgpException&lt;/span&gt; &lt;span class="n"&gt;ex&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="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Decryption failed: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&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="n"&gt;IOException&lt;/span&gt; &lt;span class="n"&gt;ex&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="nf"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"IO exception during decryption: "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ex&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;It was a lengthy war, but I emerged with a wealth of knowledge on the encryption process in terms of Symmetric and Asymmetric encryption, cryptographic algorithms such as RSA and in my opinion the improvement ECC (Elliptic curve cryptography) which offers greater security with a smaller key size, wherein the equivalent of an ECC 521 key size is equal to 15360 key size!. &lt;/p&gt;

&lt;p&gt;This is not to claim that I am now a security expert or that I've covered the entire field. as usual there are some considerations here and there, which you should be aware of and can be addressed by conducting your own security and penetration testing.&lt;/p&gt;

&lt;p&gt;Thanks and Happy Encrypting!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Link to implementation. &lt;a href="https://github.com/ibengeu/PGP" rel="noopener noreferrer"&gt;Github&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>encryption</category>
      <category>pgp</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Entry-7: Different Ways to Collections in C#</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sun, 23 Jul 2023 15:07:25 +0000</pubDate>
      <link>https://dev.to/ibengeu/different-ways-to-handle-loops-in-c-3l1l</link>
      <guid>https://dev.to/ibengeu/different-ways-to-handle-loops-in-c-3l1l</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%2F500q6ymj8ad239h7wedw.jpg" 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%2F500q6ymj8ad239h7wedw.jpg" alt="Coding image by Safar Safarov on unsplash" width="640" height="960"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This short article discusses three different strategies for handling collections using C# language, where each strategy employs a unique looping approach to achieve the same result.&lt;/p&gt;

&lt;p&gt;The implementations include a Foreach loop, a LINQ-based approach using the Select method, and a traditional For loop run on 1000 iterations. Let's analyze each strategy, including their execution times, memory usage, and CPU usage, to understand their performance characteristics.&lt;/p&gt;

&lt;p&gt;Before we begin, some key terms to note&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compile Time:&lt;/strong&gt;&lt;br&gt;
Compile time refers to the duration it takes for the compiler to process the source code and generate executable machine code. During compilation, the compiler checks the code for syntax errors, performs optimizations, and translates it into machine-readable instructions. A shorter compile time indicates that the code is processed quickly and is ready for execution, which is desirable for development efficiency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution Time:&lt;/strong&gt;&lt;br&gt;
Execution time, also known as runtime, is the time taken by a program to complete its execution once it starts running. It measures how long it takes for the program to execute all its statements and complete its tasks. A lower execution time means that the program runs faster, which is beneficial for applications that require quick responses and high performance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory Usage:&lt;/strong&gt;&lt;br&gt;
Memory usage represents the amount of memory (RAM) that a program consumes while it is running. It indicates the space required to store data, variables, and program instructions during execution. Lower memory usage is generally preferred, especially for resource-constrained environments or when dealing with large datasets, as it reduces the risk of memory-related issues like crashes or slowdowns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CPU Time:&lt;/strong&gt;&lt;br&gt;
CPU time measures the total amount of time the central processing unit (CPU) spends executing a program. It includes the time the CPU spends processing instructions for the program and any time spent waiting for external resources like I/O operations. A lower CPU time indicates that the program is using the CPU efficiently and is not overly taxing the processor, leading to better overall system performance.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strategies
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Foreach Doubling Strategy:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This strategy utilizes a foreach loop to iterate through the input list and double each element. The resulting doubled numbers are stored in a new list, which is then returned. This approach offers simplicity in syntax and is easy to read.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compile Time: 0.156s&lt;/li&gt;
&lt;li&gt;Execution Time: 0.016s&lt;/li&gt;
&lt;li&gt;Memory Usage: 96kb&lt;/li&gt;
&lt;li&gt;CPU Time: 0.016s
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ForeachDoublingStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doubledNumbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
   &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;doubledNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&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="n"&gt;doubledNumbers&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;ol&gt;
&lt;li&gt;LINQ Doubling Strategy:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In this strategy, we leverage LINQ's Select method, which provides a concise way to perform the doubling operation on each element of the input list. The Select method returns an IEnumerable that is then converted to a &lt;code&gt;List&amp;lt;int&amp;gt;&lt;/code&gt; using the &lt;code&gt;ToList()&lt;/code&gt; method.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compile Time: 0.172s&lt;/li&gt;
&lt;li&gt;Execution Time: 0.016s&lt;/li&gt;
&lt;li&gt;Memory Usage: 152kb&lt;/li&gt;
&lt;li&gt;CPU Time: 0.016s
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;LinqDoublingStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&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="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;num&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToList&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;ol&gt;
&lt;li&gt;For Loop Doubling Strategy:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This strategy employs a traditional &lt;code&gt;for&lt;/code&gt; loop to iterate through the input list and double each element. The doubled numbers are added to a new list, which is returned after the loop completes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Last Run: 3:26:47 pm&lt;/li&gt;
&lt;li&gt;Compile Time: 0.172s&lt;/li&gt;
&lt;li&gt;Execution Time: 0.016s&lt;/li&gt;
&lt;li&gt;Memory Usage: 104kb&lt;/li&gt;
&lt;li&gt;CPU Time: 0.031s
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;ForLoopDoublingStrategy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;doubledNumbers&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
   &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
   &lt;span class="p"&gt;{&lt;/span&gt;
       &lt;span class="n"&gt;doubledNumbers&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;numbers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;*&lt;/span&gt; &lt;span class="m"&gt;2&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="n"&gt;doubledNumbers&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;Each of the provided strategies use a sample which effectively doubles the elements in the input list of integers. &lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Foreach&lt;/code&gt; and &lt;code&gt;For Loop&lt;/code&gt; strategies offer similar performance, with &lt;code&gt;Foreach&lt;/code&gt; consuming slightly less memory. On the other hand, the LINQ-based &lt;code&gt;Select&lt;/code&gt; approach uses a bit more memory but remains concise and easy to maintain. &lt;/p&gt;

&lt;p&gt;To decide on the best strategy, consider the specific requirements of the application. If memory usage is a significant concern, especially for large datasets, the &lt;code&gt;Foreach&lt;/code&gt; or &lt;code&gt;For Loop&lt;/code&gt; strategy might be more suitable. These approaches can efficiently process data without creating additional memory overhead.&lt;/p&gt;

&lt;p&gt;On the other hand, if code readability, simplicity, and ease of maintenance are higher priorities, the LINQ-based approach could be the better choice. The &lt;code&gt;Select&lt;/code&gt; method offers an elegant way to perform the doubling operation, making the code more expressive and easier to manage.&lt;/p&gt;

&lt;p&gt;Ultimately, it is essential to balance code readability, simplicity, and memory efficiency based on the specific needs of the application. For critical scenarios with memory constraints, profiling different strategies with representative data can help determine the most appropriate choice. Keep in mind that different situations may warrant different strategies, so it is crucial to assess the trade-offs and select the best approach accordingly.&lt;/p&gt;

&lt;p&gt;Profiler used -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dotnetfiddle.net/KW7EW4" rel="noopener noreferrer"&gt;https://dotnetfiddle.net/KW7EW4&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programmingtips</category>
      <category>dotnet</category>
      <category>csharp</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Entry-6: [Design Patterns] - Chain of Responsibility Pattern</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Tue, 02 May 2023 17:12:52 +0000</pubDate>
      <link>https://dev.to/ibengeu/design-patterns-chain-of-responsibility-pattern-55ai</link>
      <guid>https://dev.to/ibengeu/design-patterns-chain-of-responsibility-pattern-55ai</guid>
      <description>&lt;p&gt;The chain of responsibility pattern is one of those essentials which can solve the headaches in building an authentication system in react.(or similar)&lt;/p&gt;

&lt;p&gt;it’s a &lt;strong&gt;&lt;a href="https://www.notion.so/S-in-SOLID-c043f159b92f4426a8dd3aaed51c769b" rel="noopener noreferrer"&gt;Behavioral design pattern&lt;/a&gt;&lt;/strong&gt; which encapsulates the logic for a request, passing on that request along each handler or item till it’s ignored or handled as intended.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;So how is this applied in React.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Say we would like to create an authentication system in react which checks&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If a user is an admin or regular&lt;/li&gt;
&lt;li&gt;checks if a users subscription has expired&lt;/li&gt;
&lt;li&gt;Redirects or shows the appropriate selection.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can make use of an if/else statement or violate the single responsibility principle but as more requirements arise that logic becomes messy. &lt;em&gt;plus…&lt;/em&gt; we can move handlers around to handle requests before the next eg. &lt;em&gt;check subscription before user type&lt;/em&gt;, remove if needed with minimal effort. ie, &lt;strong&gt;Reduced coupling!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Implementation&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;create an interface and contract for handling requests
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;IHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;setNext&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Handler&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="c1"&gt;// Can be named differently + (optional) - it passes the request to the next handler.&lt;/span&gt;
  &lt;span class="nf"&gt;handleRequest&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&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="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Implement&lt;/span&gt; &lt;span class="nx"&gt;Base&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;which&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="nx"&gt;common&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;all&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Implement base handler which implements logic common to all classes which would use the CoR pattern
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AbstractHandler&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;IGenericResponsibility&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;_nextHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IGenericResponsibility&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="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;addNextHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IGenericResponsibility&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;IGenericResponsibility&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;_nextHandler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;handler&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="nc"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// Any can be replaced with your type as needed&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;_nextHandler&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="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&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;_nextHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&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;ul&gt;
&lt;li&gt;create a class which makes use of the abstract class above
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// base class to handle the common request&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;checkAdmin&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle the request here, or pass it to the next handler&lt;/span&gt;
    &lt;span class="c1"&gt;// if this handler cannot handle it.&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* condition to handle the 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="cm"&gt;/* Result from handling the 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;else&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;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pass the request to the next handler&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;// we do the same above for all handlers extending the abstract or base handler.&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;checkSubscription&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractHandler&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nc"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Handle the request here, or pass it to the next handler&lt;/span&gt;
    &lt;span class="c1"&gt;// if this handler cannot handle it.&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="cm"&gt;/* condition to handle the 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="cm"&gt;/* Result from handling the 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;else&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;super&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;args&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Pass the request to the next handler&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;ul&gt;
&lt;li&gt;initialize class which makes use of the concrete handler.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkAdmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;checkAdmin&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;checkSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;checkSubscription&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;checkSubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNextHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkAdmin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//if we have more handlers we keep stacking.&lt;/span&gt;
&lt;span class="c1"&gt;//Then we trigger the handler by calling the method at which we would like to start from.&lt;/span&gt;
&lt;span class="nx"&gt;concreteHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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;Create hook which makes use of the handler
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nf"&gt;axios &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;preferred&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;axios&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preferred&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;useCOResponsibility&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkAdmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;checkAdmin&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;checkSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;checkSubscription&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;checkSubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNextHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkAdmin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//if we have more handlers we keep stacking.&lt;/span&gt;
&lt;span class="c1"&gt;//Then we trigger the handler by calling the method at which we would like to start from.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;concreteHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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;result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;condition&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;//perform condition.&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;Making use of a hook should not hinder us as well, as we can also make use of the concrete handler directly within our component ie.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;FuntionalComponent&lt;/span&gt; &lt;span class="o"&gt;=&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;checkAdmin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;checkAdmin&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;checkSubscription&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;checkSubscription&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;checkSubscription&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addNextHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;checkAdmin&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;//if we have more handlers we keep stacking.&lt;/span&gt;
&lt;span class="c1"&gt;//Then we trigger the handler by calling the method at which we would like to start from.&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;concreteHandler&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;request&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="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;condition&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;//perform condition.&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;},[&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="c1"&gt;// or a similar logic to handle a result&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;JSX&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;At the moment, the CoR is one of my favorite design patterns compared to others, such as the strategy pattern. This is because the flow of my logic moves in a sequential and logical manner with the CoR pattern, and it allows me to call one item before the other, switch out places, and apply the single responsibility and open/closed principles with less complexity. These factors result in clear and concise functionality in my code.&lt;/p&gt;

&lt;p&gt;What do you think/which is your pattern and why do you make use of it.? Feel free to send your response as a message or comment below.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Resources&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Wikipedia - &lt;strong&gt;&lt;a href="https://en.wikipedia.org/wiki/Chain-of-responsibility_pattern" rel="noopener noreferrer"&gt;Chain-of-responsibility pattern&lt;/a&gt;&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://refactoring.guru/design-patterns/chain-of-responsibility" rel="noopener noreferrer"&gt;https://refactoring.guru/design-patterns/chain-of-responsibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.javatpoint.com/behavioral-design-patterns" rel="noopener noreferrer"&gt;https://www.javatpoint.com/behavioral-design-patterns&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>designpatterns</category>
      <category>codequality</category>
      <category>techcommunity</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Entry-5: Automapper: Streamlining Object-to-Object Mapping for C# Developers</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sat, 18 Feb 2023 22:13:10 +0000</pubDate>
      <link>https://dev.to/ibengeu/automapper-streamlining-object-to-object-mapping-for-c-developers-4hl7</link>
      <guid>https://dev.to/ibengeu/automapper-streamlining-object-to-object-mapping-for-c-developers-4hl7</guid>
      <description>&lt;p&gt;Working with DTOs can be tedious, but working with AutoMapper makes it a breeze. &lt;/p&gt;

&lt;p&gt;in simple terms, it is an object-to-object mapper. This means mapping the fields of one object to another ie. &lt;/p&gt;

&lt;p&gt;Mapping...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;object1&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;field1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;field2&lt;/span&gt;
 &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// to &lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;object2&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="n"&gt;field1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;field2&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;why do we need it, you might ask. We need AutoMapper when we have a lot of fields and we want to create a data transfer object that returns only the essentials the client needs. In this case, manually instantiating both items and appending to both is time-consuming. Instead, with the help of AutoMapper, we can easily map the fields.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;see visual example below;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;say we have a user model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;PhoneNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Password&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;NoseSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;HeadSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ToeSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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;and then a DTO.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UserDTO&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;

 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;PhoneNumber&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Email&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;NoseSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;HeadSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;}&lt;/span&gt;
 &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;ToeSize&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&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;In order to make use of the DTO, we append the values such as.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;
&lt;span class="n"&gt;UserDTO&lt;/span&gt; &lt;span class="n"&gt;userDTO&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;

&lt;span class="n"&gt;FirstName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FirstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;LastName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="n"&gt;PhoneNumber&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PhoneNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="c1"&gt;// You get the drift.&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;We would be manually appending to each field. but with the help of AutoMapper, it would be simple as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="c1"&gt;// After the setup of automapper&lt;/span&gt;
&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;userMap&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;autoMapper&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Destination&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;source&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="c1"&gt;// and we are done!&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;So, the TLDR: it removes the manual task of working with Data Transfer Objects (DTOs).&lt;/p&gt;

&lt;h2&gt;
  
  
  Setup.
&lt;/h2&gt;

&lt;p&gt;We would be making use of Dependency Injection for the task, enabling us make use of the automapper config and interface any where in our app.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Steps&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the Automapper package with dependency Injection (D.I).&lt;/li&gt;
&lt;/ul&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%2Fnh91lnaq6aw2ja9gaonz.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%2Fnh91lnaq6aw2ja9gaonz.png" alt="automapper dependency injection package" width="800" height="134"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a source and Destination. 
source here means what we are mapping from and destination means, what would the final result be.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using our example from above, the source is our user model and destination is our UserDTO&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create an assembly which extends the automapper profile containing the configuration for each mapping.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ie.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;System&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;AutoMapper&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;lastbank.Database&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;lastbank.DTO&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;lastbank.Configuration&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;class&lt;/span&gt; &lt;span class="nc"&gt;AutoMapperCfg&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Profile&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AutoMapperCfg&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;CreateMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;APIUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;UserDTO&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;ReverseMap&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="n"&gt;CreateMap&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;APIUser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;CreateUserDTO&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;ReverseMap&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;p&gt;A twist above with the reverseMap, this enables us map both directions.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add the automapper service to the DI container within your program.cs file with
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddAutoMapper&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AutoMapperCfg&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;Access through your DI method&lt;/li&gt;
&lt;li&gt;Invoke Object.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;            var userMap = _mapper.Map&amp;lt;Destination&amp;gt;(Source);

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

&lt;/div&gt;



&lt;p&gt;Voila!&lt;/p&gt;

&lt;p&gt;Above we covered the basics of how to install and configure AutoMapper, as well as its more advanced features with D.I. &lt;/p&gt;

&lt;p&gt;We've seen how AutoMapper can make mapping between object types easier, more concise, and less prone to errors. It's a powerful tool for any C# developer who works with complex/non-complex object hierarchies, of which it significantly reduces the time and effort spent on manual mapping. With its continuously evolving features, AutoMapper remains an exciting and valuable tool for developers.&lt;/p&gt;

&lt;p&gt;... Also, checkout cool alternatives such as Mapster.&lt;/p&gt;

&lt;p&gt;Resource;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://docs.automapper.org/en/latest/Getting-started.html" rel="noopener noreferrer"&gt;Automapper&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=kFzkvAtni9A&amp;amp;list=PLUl9BcvgsrKYa9mUygO9lIGow-1GaNWqs&amp;amp;index=7" rel="noopener noreferrer"&gt;Trevoir williams - API Development&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Other Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research[5 min]&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>dotnetcore</category>
      <category>dotnet</category>
      <category>automapper</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Entry-4: Building a telegram client with react-native (Part 2)</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sat, 11 Feb 2023 18:47:11 +0000</pubDate>
      <link>https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-2-2jc5</link>
      <guid>https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-2-2jc5</guid>
      <description>&lt;p&gt;In my previous post on &lt;a href="https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-1-4al7"&gt;building a telegram client with react-native (Part 1)&lt;/a&gt;. I outlined the basic steps in setting up and authenticating your app with Telegram.&lt;/p&gt;

&lt;p&gt;In this post, I would be going through the process of displaying the chat list. So let's begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Setup your project and Authenticated successfully. &lt;a href="https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-1-4al7"&gt;see post&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;A User Interface setup to call the methods required.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to display the chat list we would be building upon the &lt;a href="https://github.com/tdlib/td/blob/6ba394fc411c1c6585345df7dbe1919a08489050/example/java/org/drinkless/tdlib/example/Example.java#L248" rel="noopener noreferrer"&gt;Repository Example&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variables&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;    &lt;span class="cm"&gt;/** This is the client instance created from part 1, which
        is used throughout the app. You have the option of
        creating a singleton in order to use one instance of 
        the client or create a static function which returns
        the created instance.

        But note, the client should not be instantiated more       
        than once.
    **/&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;client&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Java Method.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;

&lt;span class="cm"&gt;/** Limit here is the number of chats to return, do note 
telegram also handles the amount of chats to be returned when 
appropriate.**/&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;loadChatList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&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="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Telegram&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getClientInstance&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/** Here we run a synchronized method to avoid race conditions, situations wherein variables or stores are updated
while being accessed.

Rephrased. Since we are running on a different thread, 
we restrict access to the "getMainchatlist" variable while operations are performed on it.
**/&lt;/span&gt;
        &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMainChatList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;client&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="o"&gt;{&lt;/span&gt;

                    &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LoadChats&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ChatListMain&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseInt&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMainChatList&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;size&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;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ResultHandler&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                        &lt;span class="nd"&gt;@Override&lt;/span&gt;
                        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;onResult&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;JSONException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                            &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getConstructor&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONSTRUCTOR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;

                                    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(((&lt;/span&gt;&lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;404&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                        &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMainChatList&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                            &lt;span class="n"&gt;haveFullMainChatList&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                                            &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                                &lt;span class="n"&gt;initChatlist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                                            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                                &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                                                &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                                            &lt;span class="o"&gt;}&lt;/span&gt;
                                        &lt;span class="o"&gt;}&lt;/span&gt;

                                    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(((&lt;/span&gt;&lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// user unauthorized&lt;/span&gt;
                                        &lt;span class="nc"&gt;Telegram&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;onAuthorizationStateUpdated&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="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                                        &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Receive an error for LoadChats:"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;newLine&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                                    &lt;span class="o"&gt;}&lt;/span&gt;
                                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Ok&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CONSTRUCTOR&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                                    &lt;span class="c1"&gt;// chats had already been received through updates, let's retry request&lt;/span&gt;
                                    &lt;span class="n"&gt;loadChatList&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

                                    &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
                                &lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;
                                    &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;err&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Receive wrong response from TDLib:"&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;newLine&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                            &lt;span class="o"&gt;}&lt;/span&gt;
                        &lt;span class="o"&gt;}&lt;/span&gt;
                    &lt;span class="o"&gt;});&lt;/span&gt;

                &lt;span class="o"&gt;}&lt;/span&gt;


            &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;printStackTrace&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What the above snippet does in a nutshell is to.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check if the client instance is available&lt;/li&gt;
&lt;li&gt;Get the chat-list by calling the TDLIB API "loadchats" with its configurations&lt;/li&gt;
&lt;li&gt;If we receive a 404, this means the chat-list has been processed by TDLIB and then initialize the chat-list.&lt;/li&gt;
&lt;li&gt;In the case of a 401, we restart the authentication process.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Snippet for initialization.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="cm"&gt;/**
     * Handles the conversion to serializable data to be used in react-native
     * @throws JSONException
     */&lt;/span&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;initChatlist&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;JSONException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;java&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;util&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Iterator&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;OrderedChat&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMainChatList&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;iterator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;Gson&lt;/span&gt; &lt;span class="n"&gt;g&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;Gson&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

        &lt;span class="nc"&gt;WritableArray&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Arguments&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;createArray&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="nc"&gt;DataHandler&lt;/span&gt; &lt;span class="n"&gt;data&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;DataHandler&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;


        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;chatLimits&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMainChatList&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;iter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getChatId&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
            &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Chat&lt;/span&gt; &lt;span class="n"&gt;chat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ChatHandler&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getChat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chatId&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="kd"&gt;synchronized&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="nc"&gt;JSONObject&lt;/span&gt; &lt;span class="n"&gt;jo&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;JSONObject&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;g&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toJson&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;chat&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

                &lt;span class="nc"&gt;WritableMap&lt;/span&gt; &lt;span class="n"&gt;wm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;convertJsonToMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jo&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;pushMap&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;wm&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getJSModule&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;DeviceEventManagerModule&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;RCTDeviceEventEmitter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;emit&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"PopulatedList"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;


    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;[Snippet above] &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Due to the returned response from TDLIB not being compatible with React-Native, we convert it to JSON with the aid of GSON which is a ggogle library for easy serialization and deserialization of data.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Using the chatId as a key to access each chat, convert it to JSON, store in an array and send back as an event to React-Native &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why we make use of an iterator above is to create a "loopable" sequence as the mainChatlist is made up of a set collection, see below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;NavigableSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OrderedChat&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;mainChatList&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;TreeSet&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&amp;gt;();&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Annnnnddddd "OrderedChat"&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;OrderedChat&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;Comparable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;OrderedChat&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;chatId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ChatPosition&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

        &lt;span class="nc"&gt;OrderedChat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="n"&gt;chatId&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ChatPosition&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;chatId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;long&lt;/span&gt; &lt;span class="nf"&gt;getChatId&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;chatId&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;compareTo&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderedChat&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;order&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;order&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;order&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="nd"&gt;@Override&lt;/span&gt;
        &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Object&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="nc"&gt;OrderedChat&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;OrderedChat&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;obj&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;chatId&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;order&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;o&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;position&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;order&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;[Snippet Above]&lt;br&gt;
Built upon the repository example, this is done to quote the &lt;a href="https://core.telegram.org/tdlib/getting-started#handling-updates" rel="noopener noreferrer"&gt;official page&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The positions of chats in chat lists are managed by TDLib, so the Application only needs to listen to updates that change the chat.positions field, maintain the list of all chats, sorted by the pair (position.order, chat.id) in descending order.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Se'fini und Merci.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research[5 min]&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Entry-4: Building a telegram client with react-native (Part 1)</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sat, 11 Feb 2023 17:53:11 +0000</pubDate>
      <link>https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-1-4al7</link>
      <guid>https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-1-4al7</guid>
      <description>&lt;p&gt;it was quite cumbersome but entertaining - the notion of react-native learn once write anywhere rings true when faced with minimal apps but not with complex apps.&lt;/p&gt;

&lt;p&gt;At some point having the knowledge of the underlying language ie. Swift, Kotlin or Java speeds up the process.&lt;/p&gt;

&lt;p&gt;Although react-native has it’s good parts, being comfortable with the aforementioned languages would go along way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A couple of things learnt&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swift, Android(Java or kotlin) and bits of obj-c to comfortable write functionalities.&lt;/li&gt;
&lt;li&gt;React-native being tedious when you have to combine languages, and would recommend one to go for the native directly except of course in minimal cases.&lt;/li&gt;
&lt;li&gt;Threading and concurrency as most examples which improves the performance of the app, although a couple of tdlib methods can only be run on one thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Tdlib pre-built library. Android or build from scratch, see &lt;a href="https://github.com/tdlib/td/tree/master/example/android" rel="noopener noreferrer"&gt;TDLib Android example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a folder called &lt;strong&gt;jniLibs&lt;/strong&gt;  under main&lt;/li&gt;
&lt;li&gt;Move contents of the libs folder gotten from the built files above to &lt;strong&gt;jniLibs&lt;/strong&gt; eg. armv4 etc&lt;/li&gt;
&lt;li&gt;Move contents of tdlib→ *.java to your folder eg. nativeclient, client.java&lt;/li&gt;
&lt;li&gt;Add to build.gradle(:app) android - see, &lt;a href="https://github.com/tdlib/td/issues/1904" rel="noopener noreferrer"&gt;https://github.com/tdlib/td/issues/1904&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="n"&gt;sourceSets&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;jniLibs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;srcDirs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jniLibs&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;jni&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;srcDirs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Connect to react-native using your preferred method. either turbo-modules or legacy.&lt;/li&gt;
&lt;li&gt;C*&lt;em&gt;ode!&lt;/em&gt;*&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Begin.
&lt;/h1&gt;

&lt;p&gt;Within this module, we would cover while building upon the Java example within the &lt;strong&gt;&lt;a href="https://github.com/tdlib/td/blob/master/example/java/org/drinkless/tdlib/example/Example.java" rel="noopener noreferrer"&gt;TDLIB Repository&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication with Telegram.&lt;/li&gt;
&lt;li&gt;Display chat-list&lt;/li&gt;
&lt;li&gt;Display single chat&lt;/li&gt;
&lt;li&gt;Send and receive messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authentication with Telegram.
&lt;/h2&gt;

&lt;p&gt;To authenticate with telegram, you should have your phone number and details registered with telegram either through the app or built as an interface.&lt;/p&gt;

&lt;p&gt;A couple of functions we would need.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Building-a-telegram-client-with-react-native-Part-1-f8ff51a23dd54310a8031810bd884e7d" rel="noopener noreferrer"&gt;StartTdlib Service&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Building-a-telegram-client-with-react-native-Part-1-f8ff51a23dd54310a8031810bd884e7d" rel="noopener noreferrer"&gt;Login&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.notion.so/Building-a-telegram-client-with-react-native-Part-1-f8ff51a23dd54310a8031810bd884e7d" rel="noopener noreferrer"&gt;Verify Phone Number&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Resend OTP (exercise)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;StartTdlib&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This begins all communication to the TDLIB API&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variables.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** client instance which would be used to make calls to the TDLIB api. **/&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;client&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="cm"&gt;/** 
Used to ensure we do not start the tdlib service once more, as it would throw an error
we can check for client above as well, if we have the client, this means  the service has been started
 **/&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="n"&gt;hasStartedTdlibService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;startTdLib&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

&lt;span class="cm"&gt;/** 
 ** We check if the tdlib service has been started and then trigger the last status
**/&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasStartedTdlibService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;onAuthorizationStateUpdated&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="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// disable TDLib log and redirect fatal errors and plain log messages to a file&lt;/span&gt;
        &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SetLogVerbosityLevel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

                &lt;span class="cm"&gt;/* create a path wherein tdlib can send write logs to and throws an error with the message below if the directory cannot be accessed*/&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SetLogStream&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LogStreamFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExternalFilesDir&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="na"&gt;getAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"tdlib.log"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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="nf"&gt;IOError&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;IOException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Write access to the current directory is required"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// create client&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&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;UpdateHandler&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="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;hasStartedTdlibService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Functions not displayed from above are extracts from the repository example ie.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tdlib/td/blob/master/example/java/org/drinkless/tdlib/example/Example.java#L90" rel="noopener noreferrer"&gt;OnAuthorizationState&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tdlib/td/blob/master/example/java/org/drinkless/tdlib/example/Example.java#L371" rel="noopener noreferrer"&gt;UpdateHandler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Login
&lt;/h2&gt;

&lt;p&gt;On start of the TDLIB service, we would need to submit the phone number to receive the otp code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native (Java)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReadableMap&lt;/span&gt; &lt;span class="n"&gt;userDetails&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userDetails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"countrycode"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userDetails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"phoneNumber"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;// client here links to the variable above which has been filled by the startTdlib Method,.&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SetAuthenticationPhoneNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phoneNumber&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NativeResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pending your UI requirements, ensure you have methods which&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls the method *&lt;em&gt;**&lt;a href="https://www.notion.so/Building-a-telegram-client-with-react-native-Part-1-f8ff51a23dd54310a8031810bd884e7d" rel="noopener noreferrer"&gt;Login&lt;/a&gt;&lt;/em&gt;* from above&lt;/li&gt;
&lt;li&gt;Receives an event or promise for the next step to enter the OTP code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example submit function.&lt;/strong&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="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="o"&gt;=&amp;gt;&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="c1"&gt;// Calls the native method set above, ie. login sending the countrycode and phone number&lt;/span&gt;
                                &lt;span class="nx"&gt;TelegramModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;countrycode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;countryCode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="na"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;phoneNumber&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;ToastFeedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showError&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="c1"&gt;// perform any clean up necessary.&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;Example event listener&lt;/strong&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventEmitter&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;NativeEventEmitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TelegramModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;eventEmitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AuthorizationStateWaitCode&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Perform necessary actions when this event is received from call in submit function&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;NB&lt;/strong&gt;: Promise within the native module, is set from react native, no additional setup is required.&lt;/p&gt;

&lt;p&gt;See for more info. &lt;a href="https://reactnative.dev/docs/native-modules-android#promises" rel="noopener noreferrer"&gt;Promises&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify Phone Number
&lt;/h3&gt;

&lt;p&gt;In this phase we would have received an OTP from the &lt;a href="https://www.notion.so/Building-a-telegram-client-with-react-native-Part-1-f8ff51a23dd54310a8031810bd884e7d" rel="noopener noreferrer"&gt;login&lt;/a&gt; process set above, with the OTP gotten we make setup some functions to handle the verification&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native (JAVA)&lt;/strong&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ReactMethod&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;verifyPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;otp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&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="nx"&gt;TdApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CheckAuthenticationCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;otp&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;NativeResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promise&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;React Native&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Likewise we ensure the core process listed above ie. submit function, eventlisteners are setup to proceed with the next step&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submitOtp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;try&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;TelegramModule&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TelegramModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verifyPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;code&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="c1"&gt;// handle result here&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;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// catch errors&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;Exercise&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;see if you can implement the resend OTP phase, using the logic from above.&lt;/p&gt;

&lt;p&gt;Hopefully with this you can start or resolve issues encountered while building your own telegram client using react native.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Some issues encountered along the way.&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sending responses from android to JS.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Event Emitter does not get called.

&lt;ul&gt;
&lt;li&gt;Check for incorrect handling of updates - in my case I attached the wrong response handler&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Emitter does not send response back to react-native&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Check you are making use of the correct event or method&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;API_INVALID__ERROR&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;check for spaces or strings within the setTdlibParameters&lt;/li&gt;
&lt;li&gt;Make use of the second constructor with parameters.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Making use of the react application context in other classes

&lt;ul&gt;
&lt;li&gt;the idea was to instatiate the variable for the context with key of static when created and then access it through a static method.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Execution failed for task ':app:mergeDebugResources' occur while running the app&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;In my case it was an XML file having the wrong property ***&lt;strong&gt;&lt;em&gt;“app:…”&lt;/em&gt;&lt;/strong&gt;*** under a wrong layout. checking for resources eg. drawables, fonts, xml etc could resolve this issue.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Duplicate class androidx.lifecycle.ViewModelLazy found in modules jetified-lifecycle-viewmodel-ktx-2.3.1-runtime&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As the error suggests there is a duplicate class used by one of the packages or your implementation with regards to the lifecycle - adding the following code unifies the dependency &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is added on under app → build.gradle&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```
implementation "androidx.lifecycle:lifecycle-viewmodel:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
```
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Textview or views not populated with data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;each side of the display should contain the same ids as giving it a different name would not allow it to be populated.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-2-2jc5"&gt;Building a Telegram Client - Part 2 &lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Building a telegram client with react-native (Part 1)</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sun, 05 Feb 2023 17:07:19 +0000</pubDate>
      <link>https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-1-4573</link>
      <guid>https://dev.to/ibengeu/building-a-telegram-client-with-react-native-part-1-4573</guid>
      <description>&lt;p&gt;Building a telegram client was quite cumbersome but entertaining, stretching my knowledge and learning process which is key to growth &lt;/p&gt;

&lt;p&gt;The notion of react-native learn once write anywhere rings true when faced with minimal apps but not with complex apps.&lt;/p&gt;

&lt;p&gt;Although react-native has it’s good parts, being comfortable with the aforementioned languages would go along way even speeding up the process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A couple of things learnt&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Swift, Android(Java or kotlin) and bits of obj-c to comfortable write functionalities.&lt;/li&gt;
&lt;li&gt;React-native being tedious when you have to combine languages, and would recommend one to go for the native directly except of course in minimal cases.&lt;/li&gt;
&lt;li&gt;Threading and concurrency as most examples which improves the performance of the app, although a couple of tdlib methods can only be run on one thread.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;If you are making use of an expo managed app, the process still applies.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tdlib pre-built library. Android or build from scratch, see &lt;a href="https://github.com/tdlib/td/tree/master/example/android" rel="noopener noreferrer"&gt;TDLib Android example&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Create a folder called &lt;strong&gt;jniLibs&lt;/strong&gt;  under main&lt;/li&gt;
&lt;li&gt;Move contents of the libs folder gotten from the built files above to &lt;strong&gt;jniLibs&lt;/strong&gt; eg. armv4 etc&lt;/li&gt;
&lt;li&gt;Move contents of tdlib→ *.java to your folder eg. nativeclient, client.java
...
See Folder structure below, peek the jniLibs folder.&lt;/li&gt;
&lt;/ul&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%2Fb8f9bnseovw5b2i4gcyv.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%2Fb8f9bnseovw5b2i4gcyv.png" alt="Folder structure" width="656" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add to build.gradle(:app) android - see, &lt;a href="https://github.com/tdlib/td/issues/1904" rel="noopener noreferrer"&gt;https://github.com/tdlib/td/issues/1904&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;        &lt;span class="n"&gt;sourceSets&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;jniLibs&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;srcDirs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;main&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;jniLibs&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
            &lt;span class="n"&gt;jni&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;srcDirs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Connect to react-native using your preferred method. either turbo-modules or legacy.&lt;/li&gt;
&lt;li&gt;Code!&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Begin.
&lt;/h2&gt;

&lt;p&gt;Within this module, we would cover while building upon the Java example within the &lt;strong&gt;&lt;a href="https://github.com/tdlib/td/blob/master/example/java/org/drinkless/tdlib/example/Example.java" rel="noopener noreferrer"&gt;TDLIB Repository&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication with Telegram.&lt;/li&gt;
&lt;li&gt;Display chat-list&lt;/li&gt;
&lt;li&gt;Display single chat&lt;/li&gt;
&lt;li&gt;Send and receive messages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Authentication with Telegram.
&lt;/h2&gt;

&lt;p&gt;To authenticate with telegram, you should have your phone number and details registered with telegram either through the app or built as an interface.&lt;/p&gt;

&lt;p&gt;A couple of functions we would need.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;StartTdlib Service&lt;/li&gt;
&lt;li&gt;Login&lt;/li&gt;
&lt;li&gt;Verify Phone Number&lt;/li&gt;
&lt;li&gt;Resend OTP (exercise)&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;StartTdlib&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;This begins all communication to the TDLIB API&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Variables.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/** client instance which would be used to make calls to the TDLIB api. **/&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt; &lt;span class="n"&gt;client&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="cm"&gt;/** 
Used to ensure we do not start the tdlib service once more, as it would throw an error
we can check for client above as well, if we have the client, this means  the service has been started
 **/&lt;/span&gt;
&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;Boolean&lt;/span&gt; &lt;span class="n"&gt;hasStartedTdlibService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Method&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;startTdLib&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="nc"&gt;InterruptedException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

&lt;span class="cm"&gt;/** 
 ** We check if the tdlib service has been started and then trigger the last status
**/&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hasStartedTdlibService&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;onAuthorizationStateUpdated&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="k"&gt;return&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// disable TDLib log and redirect fatal errors and plain log messages to a file&lt;/span&gt;
        &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SetLogVerbosityLevel&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

                &lt;span class="cm"&gt;/* create a path wherein tdlib can send write logs to and throws an error with the message below if the directory cannot be accessed*/&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;execute&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SetLogStream&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;LogStreamFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getExternalFilesDir&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="na"&gt;getAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;"tdlib.log"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;)))&lt;/span&gt; &lt;span class="k"&gt;instanceof&lt;/span&gt; &lt;span class="nc"&gt;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;Error&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&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="nf"&gt;IOError&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;IOException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Write access to the current directory is required"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// create client&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;create&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;UpdateHandler&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="o"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;hasStartedTdlibService&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Functions not displayed from above are extracts from the repository example ie.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/tdlib/td/blob/master/example/java/org/drinkless/tdlib/example/Example.java#L90" rel="noopener noreferrer"&gt;OnAuthorizationState&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/tdlib/td/blob/master/example/java/org/drinkless/tdlib/example/Example.java#L371" rel="noopener noreferrer"&gt;UpdateHandler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Login
&lt;/h2&gt;

&lt;p&gt;On start of the TDLIB service, we would need to submit the phone number to receive the OTP code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native (Java)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;ReadableMap&lt;/span&gt; &lt;span class="n"&gt;userDetails&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Promise&lt;/span&gt; &lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;userDetails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"countrycode"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;userDetails&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"phoneNumber"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;// client here links to the variable above which has been filled by the startTdlib Method,.&lt;/span&gt;
        &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;send&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;TdApi&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;SetAuthenticationPhoneNumber&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phoneNumber&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="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;NativeResponse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;promise&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

   &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;React Native&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Pending your UI requirements, ensure you have methods which&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Calls the method *&lt;em&gt;**Login&lt;/em&gt;* from above&lt;/li&gt;
&lt;li&gt;Receives an event or promise for the next step to enter the OTP code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example submit function.&lt;/strong&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="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="o"&gt;=&amp;gt;&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="c1"&gt;// Calls the native method set above, ie. login sending the countrycode and phone number&lt;/span&gt;
                                &lt;span class="nx"&gt;TelegramModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;login&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
                &lt;span class="na"&gt;countrycode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;countryCode&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
                &lt;span class="na"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;phoneNumber&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="k"&gt;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;ToastFeedback&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;showError&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;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;finally&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                        &lt;span class="c1"&gt;// perform any clean up necessary.&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;Example event listener&lt;/strong&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eventEmitter&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;NativeEventEmitter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;TelegramModule&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;eventEmitter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;AuthorizationStateWaitCode&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// Perform necessary actions when this event is received from call in submit function&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;NB&lt;/strong&gt;: Promise within the native module, is set from react native, no additional setup is required.&lt;/p&gt;

&lt;p&gt;See for more info. &lt;a href="https://reactnative.dev/docs/native-modules-android#promises" rel="noopener noreferrer"&gt;Promises&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify Phone Number
&lt;/h3&gt;

&lt;p&gt;In this phase we would have received an OTP from the &lt;a href="https://www.notion.so/Building-a-telegram-client-with-react-native-Part-1-f8ff51a23dd54310a8031810bd884e7d" rel="noopener noreferrer"&gt;login&lt;/a&gt; process set above, with the OTP gotten we make setup some functions to handle the verification&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Native (JAVA)&lt;/strong&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;ReactMethod&lt;/span&gt;
    &lt;span class="kr"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;verifyPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="nx"&gt;otp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt; &lt;span class="nx"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&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="nx"&gt;TdApi&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;CheckAuthenticationCode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;otp&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;NativeResponse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;promise&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;React Native&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Likewise we ensure the core process listed above ie. submit function, eventlisteners are setup to proceed with the next step&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;submitOtp&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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;try&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;TelegramModule&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;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;TelegramModule&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;verifyPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getValues&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;code&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;result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                                &lt;span class="c1"&gt;// handle result here&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;catch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;any&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="c1"&gt;// catch errors&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;Exercise&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;see if you can implement the resend OTP phase, using the logic from above.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Some issues encountered along the way.&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Sending responses from android to JS.&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Event Emitter does not get called.

&lt;ul&gt;
&lt;li&gt;Check for incorrect handling of updates - in my case I attached the wrong response handler&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Emitter does not send response back to react-native&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Check you are making use of the correct event or method&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;API_INVALID__ERROR&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;check for spaces or strings within the setTdlibParameters&lt;/li&gt;
&lt;li&gt;Make use of the second constructor with parameters.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;Making use of the react application context in other classes

&lt;ul&gt;
&lt;li&gt;the idea was to instatiate the variable for the context with key of static when created and then access it through a static method.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;strong&gt;Execution failed for task ':app:mergeDebugResources' occur while running the app&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;In my case it was an XML file having the wrong property ***&lt;strong&gt;&lt;em&gt;“app:…”&lt;/em&gt;&lt;/strong&gt;*** under a wrong layout. checking for resources eg. drawables, fonts, xml etc could resolve this issue.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Duplicate class androidx.lifecycle.ViewModelLazy found in modules jetified-lifecycle-viewmodel-ktx-2.3.1-runtime&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As the error suggests there is a duplicate class used by one of the packages or your implementation with regards to the lifecycle - adding the following code unifies the dependency &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is added on under app → build.gradle&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;```
implementation "androidx.lifecycle:lifecycle-viewmodel:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
```
&lt;/code&gt;&lt;/pre&gt;




&lt;/li&gt;

&lt;li&gt;

&lt;p&gt;&lt;strong&gt;Textview or views not populated with data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;each side of the display should contain the same ids as giving it a different name would not allow it to be populated.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In conclusion, building a Telegram clone with React-Native is a great way to explore the capabilities of this powerful framework. By following the steps outlined in this blog post, you should now have a basic understanding of how to set up the project native(java) and react-native.&lt;/p&gt;

&lt;p&gt;Watch out for Part two as I would be taking a look at building the chat list and chat screens.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research[5 min]&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>backenddevelopment</category>
      <category>database</category>
      <category>scalability</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>Entry-3: Display Image with Intent (React-native)</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Sun, 04 Dec 2022 13:24:27 +0000</pubDate>
      <link>https://dev.to/ibengeu/display-image-with-intent-react-native-4lac</link>
      <guid>https://dev.to/ibengeu/display-image-with-intent-react-native-4lac</guid>
      <description>&lt;p&gt;A simple way I came up with to open an image, given a file path linked to the internal storage on mobile (Android)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;openFileWithIntent&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;completeFilePath&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;directory&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

                &lt;span class="c1"&gt;//convert file path to File&lt;/span&gt;
        &lt;span class="nc"&gt;File&lt;/span&gt; &lt;span class="n"&gt;newFile&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;File&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;valueOf&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Uri&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileName&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
                &lt;span class="c1"&gt;// convert create content Uri for sharing with other apps&lt;/span&gt;
        &lt;span class="nc"&gt;Uri&lt;/span&gt; &lt;span class="n"&gt;contentUri&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;getUriForFile&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getApplication&lt;/span&gt; &lt;span class="nf"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getPackageName&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;".fileprovider"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;newFile&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

                &lt;span class="c1"&gt;//create an intent&lt;/span&gt;
        &lt;span class="nc"&gt;Intent&lt;/span&gt; &lt;span class="n"&gt;intent&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;Intent&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
                &lt;span class="c1"&gt;// set the action type &lt;/span&gt;
        &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setAction&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ACTION_VIEW&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;// set the data and mime type&lt;/span&gt;
                &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;mimeType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;
        &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;setDataAndType&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;contentUri&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;mimeType&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;// Grant temporary access to application opening the file&lt;/span&gt;
        &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFlags&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_READ_URI_PERMISSION&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_GRANT_WRITE_URI_PERMISSION&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;// Due to context being outside an activity, we add the flag.&lt;/span&gt;
        &lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;addFlags&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Intent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;FLAG_ACTIVITY_NEW_TASK&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
                &lt;span class="c1"&gt;// Launch file chooser&lt;/span&gt;
        &lt;span class="n"&gt;reactContext&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;startActivity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;intent&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
 &lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to your android manifest&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;
&lt;span class="nt"&gt;&amp;lt;provider&lt;/span&gt;
&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"androidx.core.content.FileProvider"&lt;/span&gt;
&lt;span class="na"&gt;android:authorities=&lt;/span&gt;&lt;span class="s"&gt;"${applicationId}.fileprovider"&lt;/span&gt;
&lt;span class="na"&gt;android:exported=&lt;/span&gt;&lt;span class="s"&gt;"false"&lt;/span&gt;
&lt;span class="na"&gt;android:grantUriPermissions=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;meta-data&lt;/span&gt;
&lt;span class="na"&gt;android:name=&lt;/span&gt;&lt;span class="s"&gt;"android.support.FILE_PROVIDER_PATHS"&lt;/span&gt;
&lt;span class="na"&gt;android:resource=&lt;/span&gt;&lt;span class="s"&gt;"@xml/file_paths"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/provider&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We create a file path.xml for above “******&lt;strong&gt;&lt;em&gt;android:resource….”&lt;/em&gt;&lt;/strong&gt;******&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0"encoding="utf-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;pathsxmlns:android&lt;/span&gt;&lt;span class="err"&gt;="http://schemas.android.com/apk/res/android"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;external-files-pathname&lt;/span&gt;&lt;span class="err"&gt;="photos"&lt;/span&gt;&lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"photos/"&lt;/span&gt;  &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/paths&amp;gt;&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;And that’s it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep dive.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/reference/androidx/core/content/FileProvider" rel="noopener noreferrer"&gt;FileProvider | Android developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/training/data-storage" rel="noopener noreferrer"&gt;Data and file storage overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.android.com/reference/android/content/Intent?hl=en" rel="noopener noreferrer"&gt;Intent | Android developer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research[5 min]&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>reactnative</category>
      <category>snippets</category>
      <category>java</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Entry-2: ByteArray conversion (React-native)</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Fri, 02 Dec 2022 17:39:47 +0000</pubDate>
      <link>https://dev.to/ibengeu/bytearray-conversion-react-native-23ai</link>
      <guid>https://dev.to/ibengeu/bytearray-conversion-react-native-23ai</guid>
      <description>&lt;p&gt;Tasked with building a chat client with the telegram API (Post coming soon), I encountered this issue wherein the byte array had to be converted to a base64 string to display a thumbnail.&lt;/p&gt;

&lt;p&gt;After a couple of hours of research with no solution in sight of which I did not need aspirin for, the following solution below settled it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()];&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
    &lt;span class="cm"&gt;/*
     * In this context the values of the array is parsed as a string hence the method 'getString'.
     */&lt;/span&gt;
    &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Byte&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseByte&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example with a Base64Converter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FileToBase64&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;convertToBase64&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;imageBytes&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nc"&gt;Base64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;encodeBase64String&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;imageBytes&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Full code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@ReactMethod&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;convertToBase64&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Readable&lt;/span&gt; &lt;span class="nc"&gt;ArraybyteArray&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="nc"&gt;Callback&lt;/span&gt; &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;bytes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;()];&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inti&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++){&lt;/span&gt;
        &lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Byte&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseByte&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;byteArray&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getString&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Regular callback gotten from react native&lt;/span&gt;
&lt;span class="c1"&gt;// see - https://reactnative.dev/docs/native-modules-android#callbacks&lt;/span&gt;
    &lt;span class="n"&gt;callback&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;invoke&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="nc"&gt;FileToBase64&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;convertToBase64&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bytes&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  TLDR
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Send the byte to the native OS &lt;/li&gt;
&lt;li&gt;Convert and return to react-native.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;PS: Do comment below if further explanation is required, I am happy to oblige!. &lt;/p&gt;

&lt;p&gt;Cheers (:&lt;/p&gt;

&lt;h2&gt;
  
  
  External links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Twitter&lt;/strong&gt;: &lt;a href="https://twitter.com/etieno_u" rel="noopener noreferrer"&gt;@benny_wayn&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>socialmedia</category>
      <category>twitter</category>
    </item>
    <item>
      <title>Entry-1: S - in SOLID</title>
      <dc:creator>ibenge Uforo</dc:creator>
      <pubDate>Thu, 24 Nov 2022 20:11:59 +0000</pubDate>
      <link>https://dev.to/ibengeu/s-in-solid-1j4m</link>
      <guid>https://dev.to/ibengeu/s-in-solid-1j4m</guid>
      <description>&lt;p&gt;There is a common misunderstanding at-least from articles and videos on the topic where the &lt;strong&gt;"&lt;em&gt;S&lt;/em&gt;"&lt;/strong&gt; short for the single responsibility principle has been mentioned to mean. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A module should do just one thing.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Although there is a principle like that, this does not capture the entire idea. What the “*&lt;strong&gt;&lt;em&gt;S”&lt;/em&gt;&lt;/strong&gt;* essentially was intended to mean is.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A module should be responsible to one, and only one, actor."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The term actor refers to a group (consisting of one or more stakeholders or users) that requires a change in the module.&lt;/p&gt;

&lt;p&gt;where a module is regarded as a source file. a cohesive set of functions and data structures.&lt;/p&gt;

&lt;h3&gt;
  
  
  Still here? let’s go further…
&lt;/h3&gt;

&lt;p&gt;A way we could discuss this is in the results. say we have a student class which has the following functions, calculateFees(), calculateClassHours().&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Student&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateFees&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="c1"&gt;//logic&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateClassHours&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="c1"&gt;//logic&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This class violates the SRP because those two methods are responsible to two very different actors.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The calculateFees() method is specified by the accounting department, which reports to a financial officer&lt;/li&gt;
&lt;li&gt;The calculateClassHours() method is specified and used by the Lecturers, which reports to the H.O.D for some reason to the team.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From a bird’s eye-view, no deep thoughts into the matter, the code above will work as intended but will lead to some challenges. ie. making the code reusable,tight coupling etc. and due to the way programs tend to work ie. the larger the code-base -&amp;gt; the proportional logic, making it even harder to understand what is going on.&lt;/p&gt;

&lt;h3&gt;
  
  
  So… How can we solve?.
&lt;/h3&gt;

&lt;p&gt;A simple way would be to incorporate a design pattern called the &lt;strong&gt;Facade,&lt;/strong&gt; which could mean a figure head for the methods, wherein we move the core logic to a separate class and then make use of those classes in the facade. Well confusing… see below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;// First, we create the student facade&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;StudentFacade&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateFees&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args2&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt; &lt;span class="c1"&gt;// this should have types but we digress&lt;/span&gt;

    &lt;span class="c1"&gt;//perform logic to calculate the fees.&lt;/span&gt;
    &lt;span class="nc"&gt;HourReporter&lt;/span&gt; &lt;span class="n"&gt;hourReporter&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;HourReporter&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;hourReporter&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;reportHours&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;

    &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateClassHours&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;args1&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;args2&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
   &lt;span class="c1"&gt;//logic&lt;/span&gt;
    &lt;span class="nc"&gt;FeeCalculator&lt;/span&gt; &lt;span class="n"&gt;feeCalculator&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;FeeCalculator&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;feeCalculator&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;calculateFees&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HourReporter&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;reportHours&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="c1"&gt;//logic&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FeeCalculator&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;calculateFees&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;
        &lt;span class="c1"&gt;//logic&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now the classes are not tightly coupled + the student facade contains very little code. It is responsible for instantiating and delegating to the classes with the functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Konclushun.
&lt;/h3&gt;

&lt;p&gt;The SRP has the tendency to be easily misunderstood due to the name of which I hopefully clarify with some examples and improvements we can make going forward. so…what next?&lt;/p&gt;

&lt;p&gt;You could get the Book by Uncle bob on Clean architecture, this goes deeper or dive into the references (excluding the book) to have a feel. Connect with me on the linkedIn or twitter, comment (I would love to see your thoughts), throw me a question or do something out of the blue you fancy.&lt;/p&gt;

&lt;p&gt;That being said, this is all i have for now, thanks for coming to my talk.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Single-responsibility_principle" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Single-responsibility_principle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=xWk6jvqyhAQ" rel="noopener noreferrer"&gt;The Facade Pattern Explained and Implemented in Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Clean Architecture - Robert C. Martin , SRP: The Single Responsibility Principle chapter 7.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;External Links&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LinkedIn&lt;/strong&gt;: &lt;a href="https://www.linkedin.com/in/ibenge-uforo/" rel="noopener noreferrer"&gt;Ibenge-uforo&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ongoing&lt;/strong&gt; &lt;strong&gt;Research&lt;/strong&gt;: &lt;a href="https://docs.google.com/forms/d/e/1FAIpQLScKBo1VQvEVpvxKbOamhWq02uQU8HlgUPq576F-LD3yTljkwg/viewform" rel="noopener noreferrer"&gt;Social Survey&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aspdotnet</category>
      <category>csharp</category>
      <category>designpatterns</category>
      <category>solidprinciples</category>
    </item>
  </channel>
</rss>
