How to make API calls in Ionic Capacitor Apps
Tags: ionic, capacitor, angular, api
Published: 2021-08-19 21:10:48

<main role="main"><article class=" u-minHeight100vhOffset65 u-overflowHidden postArticle postArticle--full is-withAccentColors" lang="en"><div class="postArticle-content js-postField js-notesSource editable" id="editor_7" g_editable="true" role="textbox" contenteditable="true" data-default-value="Title
Tell your story…"><section name="9a37" class="section section--body section--first"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><p name="f76f" class="graf graf--p graf-after--figure">In this post, we will learn how to make REST API calls from an Ionic Capacitor app. This might sound very trivial feature but it actually becomes confusing because of a lot of options available and even becomes an issue because of origin restrictions and CORS issues.</p><p name="cfec" class="graf graf--p graf-after--p">We will explore various options to do these API calls in Ionic (Capacitor) apps, and test the same in Web, Android and iOS apps. Although I’m using a Capacitor app for demo, the solutions are applicable on Cordova as well.</p><h4 name="663e" class="graf graf--h4 graf-after--p">Frameworks</h4><p name="64c3" class="graf graf--p graf-after--h4">All the options we explore in this post are equally applicable to any of the front-end framework, be it Vanilla JS, Angular, React or Vue. For demo purpose we will use <strong class="markup--strong markup--p-strong">Angular</strong> front-end here.</p><p name="bb0c" class="graf graf--p graf-after--p">Also, for build environment we will stick to Capacitor. But we’ll see that Capacitor can use Cordova plugins as well.</p><h3 name="2e46" class="graf graf--h3 graf-after--p">REST API call&nbsp;issues</h3><p name="837c" class="graf graf--p graf-after--h3">Before we explore the options to do http API calls, we need to understand why different options exist and how they are different.</p><p name="3bb1" class="graf graf--p graf-after--p">When we make REST API calls to a server, we often encounter CORS (<a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Cross-Origin Resource Sharing</a>) issues. This happens because our REST API calls contain the information of the request’s origin. E.g. If we are making the call from <code class="markup--code markup--p-code">ionic serve</code>&nbsp;, the origin will be <code class="markup--code markup--p-code">http://localhost:8100</code> or similar. The server receiving the request decides whether it will allow an API call from this origin or not. More info in <a href="https://ionicframework.com/docs/troubleshooting/cors"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic’s documentation.</a></p><p name="b276" class="graf graf--p graf-after--p">Similarly when you make API calls from Ionic Capacitor Android or iOS app, the origin is <code class="markup--code markup--p-code">capacitor://localhost</code> and <code class="markup--code markup--p-code">http://localhost</code> respectively. For Cordova it is <code class="markup--code markup--p-code">ionic://localhost</code> in iOS, and <code class="markup--code markup--p-code"><a href="http://localhost"  class="markup--anchor markup--p-anchor" target="_blank">http://localhost</a></code> for android. These origins, again, will not be allowed in standard server like Firebase cloud, wooCommerce or Payment gateways etc.</p><h4 name="8a34" class="graf graf--h4 graf-after--p">Case 1 —&hairsp;If you have your own server, OR the server has no origin restriction</h4><p name="60c6" class="graf graf--p graf-after--h4">Life’s good then. If you have your own server where your API calls are ‘hitting’, you can make changes to allow these origins in the requests and problem solved. This can almost exclusively happen only if you are deploying the front-end and back-end yourself.</p><p name="3655" class="graf graf--p graf-after--p">If the server is not in your control, AND the server has no origin restriction, your API calls will still go through without any issue.</p><p name="4a6e" class="graf graf--p graf-after--p">In this case, we can use Angular Http Client for making REST API Calls. We’ll explore more on this in next section.</p><p name="1ecc" class="graf graf--p graf-after--p">Since not every server is relaxed in origin restrictions, we need some other solution to avoid CORS issues.</p><h4 name="24b4" class="graf graf--h4 graf-after--p">Case 2— You don’t have control over the&nbsp;server</h4><p name="bc74" class="graf graf--p graf-after--h4">This is the case most of the times. You need to make sure your requests are going through some kind of proxy (outside the webview), even if the request is actually made from the native app or localhost.</p><p name="f28c" class="graf graf--p graf-after--p"><a href="https://ionicframework.com/blog/handling-cors-issues-in-ionic/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">This old blog</a> sheds some light on possible options to avoid CORS issues in Ionic. But there are some new methods we can implement for this issues</p><h3 name="1053" class="graf graf--h3 graf-after--p">Choices in Ionic Capacitor apps for Http API&nbsp;calls</h3><p name="1658" class="graf graf--p graf-after--h3">For making REST API calls, we have following options</p><ol class="postList"><li name="d4b7" class="graf graf--li graf-after--p"><strong class="markup--strong markup--li-strong">Fetch</strong>&hairsp;—&hairsp;Default API to make Http calls</li><li name="b434" class="graf graf--li graf-after--li"><a href="https://angular.io/api/common/http/HttpClient"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--li-strong">Angular HttpClient</strong></a> (Since we are using Angular for Demo. Similar options might be there in React as well) —This is Angular’s default way of making Http calls. If doesn’t fix CORS issues, but has few advantages over fetch API. You can check the advantages in <a href="https://stackoverflow.com/a/57038001"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">this comparison.</a></li><li name="cdc0" class="graf graf--li graf-after--li"><a href="https://ionicframework.com/docs/native/http/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--li-strong">@ionic-native/http plugin&hairsp;</strong></a>—&hairsp;Works with <a href="https://github.com/silkimen/cordova-plugin-advanced-http"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">cordova-plugin-advanced-http</a>&hairsp;—&hairsp;Works only on device, so development is difficult. Fixes the CORS issues.</li><li name="98be" class="graf graf--li graf-after--li"><a href="https://github.com/sneas/ionic-native-http-connection-backend"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--li-strong">Ionic Native Http Connection Backend</strong></a><strong class="markup--strong markup--li-strong">&hairsp;</strong>—&hairsp;This package combines the above two. Essentially Angular HttpClient will work in browser, and will switch to @ionic-native/http when on device. Fixes CORS issue.</li></ol><p name="c9c0" class="graf graf--p graf-after--li">Option #3 looks good for our case, but involves Cordova plugins. This is OK if your app uses Cordova, but for Capacitor you might wanna avoid Cordova plugins. This leaves us with the final option</p><p name="9186" class="graf graf--p graf-after--p">5. <a href="https://github.com/capacitor-community/http"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank"><strong class="markup--strong markup--p-strong">Capacitor/Http plugin</strong>&hairsp;</a>—&hairsp;Works in browser, Android and iOS. Fixes CORS issue. This plugin essentially does the same as Option#3, but with less number of dependencies.</p><p name="d039" class="graf graf--p graf-after--p">Let’s explore all these options with code samples and see their limitations.</p><h3 name="61ae" class="graf graf--h3 graf-after--p">Demo Server</h3><p name="310f" class="graf graf--p graf-after--h3">We will make a Firebase server (local) using <code class="markup--code markup--p-code">firebase serve</code> and use it for the testing purpose. This is a standard method to run Firebase server locally, OR you can use <strong class="markup--strong markup--p-strong">Firebase Emulator</strong>, which is an advanced version of <code class="markup--code markup--p-code">firebase serve</code>&nbsp;. Here’s a short blog on <a href="https://enappd.com/blog/how-to-use-firebase-emulators-with-ionic-angular-applications/163"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">how to run Firebase Emulator locally</a>.</p><p name="3a12" class="graf graf--p graf-after--p">Once the server is up, we will access it from all three platforms&hairsp;—&hairsp;Web, Android and iOS.</p><h4 name="00dd" class="graf graf--h4 graf-after--p">How to access locally run server from&nbsp;device</h4><p name="6ef0" class="graf graf--p graf-after--h4">You might be wondering how to access a locally run server (running on localhost:XXXX) from your device when you build the app.</p><ul class="postList"><li name="ab54" class="graf graf--li graf-after--p">First you need to make sure your device is on the same WiFi as your server system</li><li name="ed26" class="graf graf--li graf-after--li">You need to know the IPv4 of your system. For mac, find it with <code class="markup--code markup--li-code">ifconfig</code>&nbsp;, for windows <code class="markup--code markup--li-code">ipconfig</code>&nbsp;. It will be something like <code class="markup--code markup--li-code">192.168.x.x</code> which is standard for local systems using a WiFi router</li><li name="b340" class="graf graf--li graf-after--li">Instead of default serve, you need to use <code class="markup--code markup--li-code">firebase serve -o YOUR_IP</code>&nbsp;, replace <code class="markup--code markup--li-code">YOUR_IP</code> with your actual IPv4 address</li><li name="ff18" class="graf graf--li graf-after--li">When calling APIs, use this IP as the server address, with firebase serve port number, which defaults to 5000</li></ul><h4 name="8ba1" class="graf graf--h4 graf-after--li">Firebase functions</h4><p name="f890" class="graf graf--p graf-after--h4">Firebase functions essentially behave like <code class="markup--code markup--p-code">view</code> in Django, or API methods in node (Firebase is node!). Following code shows the 4 standard methods and 4 CORS wrapped methods. (If you are new to Firebase functions, check this blog for <a href="https://enappd.com/blog/firebase-cloud-functions-in-ionic-5-complete-guide/166"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Firebase Cloud functions with Ionic</a>)</p><figure tabindex="0" contenteditable="false" name="1df9" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 164.143%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/eefb286a925fb3501a786b3d3ac56696.js %}</div></div></figure><p name="a062" class="graf graf--p graf-after--figure">Note that there’s not much being done in the methods, like fetching some data from DB, or writing a new entry. All those functionalities lay ahead of this point, and these bare methods will serve to prove the point of CORS / restriction which we are trying to understand, with different libraries.</p><p name="7fb5" class="graf graf--p graf-after--p">The API method URL i.e. <code class="markup--code markup--p-code"><a href="http://%24%7Bthis.localhost%7D:5000/ionic4fullapp/us-central1/getData"  class="markup--anchor markup--p-anchor" rel="nofollow noopener"    target="_blank">http://192.168.0.7:5000/ionic4fullapp/us-central1/getData</a></code> in my case, will be output in terminal when you run <code class="markup--code markup--p-code">firebase serve</code> or <code class="markup--code markup--p-code">emulate</code> command.</p><h3 name="9174" class="graf graf--h3 graf-after--p">Testing Methodology</h3><p name="66de" class="graf graf--p graf-after--h3">We will</p><ul class="postList"><li name="7240" class="graf graf--li graf-after--p">Make API calls to a sample Firebase server which has 4 methods&hairsp;—&hairsp;<code class="markup--code markup--li-code">getData</code>(GET), <code class="markup--code markup--li-code">postData</code>(POST), <code class="markup--code markup--li-code">putData</code>(PUT), <code class="markup--code markup--li-code">deleteData</code>(DELETE) which allows all origins and,<br>&nbsp;4 methods <code class="markup--code markup--li-code">_getData</code>(GET), <code class="markup--code markup--li-code">_postData</code>(POST), <code class="markup--code markup--li-code">_putData</code>(PUT), <code class="markup--code markup--li-code">_deleteData</code>(DELETE) which put CORS restrictions (by default Firebase feature).<br>The “unrestricted” APIs are basically wrapped in CORS module, which has the setting to allow all origins.</li><li name="1765" class="graf graf--li graf-after--li">We’ll explore both these API servers from localhost (web) and device (Android/iOS)&hairsp;—&hairsp;all calling the same server. When using localhost (web), you can <code class="markup--code markup--li-code">firebase serve</code> normally as well (without IP info)</li><li name="4112" class="graf graf--li graf-after--li">We will test these methods for all 5 options we mentioned in Choices section above.</li></ul><h3 name="2efa" class="graf graf--h3 graf-after--li">Demo App for Http&nbsp;Calls</h3><p name="4f6b" class="graf graf--p graf-after--h3">We will make a demo Ionic Angular Capacitor app to test the above. Creating the app is very simple. Run
```
$ ionic start httpTester sidemenu --type=angular --capacitor
```
<p name="4884" class="graf graf--p graf-after--pre">The app name is <code class="markup--code markup--p-code">httpTester</code>&nbsp;, type is <code class="markup--code markup--p-code">sidemenu</code> and it incorporates Angular and Capacitor.</p><p name="22ac" class="graf graf--p graf-after--p">My environment is —</p><pre name="7576" class="graf graf--pre graf-after--p"><strong class="markup--strong markup--pre-strong">Ionic</strong>:<br>Ionic CLI : 6.16.3<br>Capacitor: 3.0.2</pre><pre name="fc33" class="graf graf--pre graf-after--pre"><strong class="markup--strong markup--pre-strong">Utility</strong>:<br>cordova-res : 0.15.3<br>native-run  : 1.4.0</pre><pre name="f031" class="graf graf--pre graf-after--pre"><strong class="markup--strong markup--pre-strong">System</strong>:<br>NodeJS : v14.15.4<br>npm    : 7.17.0<br>OS     : macOS Big Sur</pre><p name="f50f" class="graf graf--p graf-after--pre">I have made custom UI to display the behavior across all options. Here’s a sample Page for Fetch API</p><figure tabindex="0" contenteditable="false" name="1e85" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 277px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 216.6%;"></div><img class="graf-image" data-image-id="1*Fcc4-UkTDAecXiRC1XmpNQ.png" data-width="277" data-height="600" alt="Demo app for testing Ionic Capacitor Http calls" src="https://cdn-images-1.medium.com/max/800/1*Fcc4-UkTDAecXiRC1XmpNQ.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Demo app UI for testing Ionic Capacitor Http&nbsp;calls</figcaption></figure><p name="3a4e" class="graf graf--p graf-after--figure">You can see the ❌ and ✅ marks for success and error in API calls. We’ll perform this routine on all</p><ul class="postList"><li name="98cf" class="graf graf--li graf-after--p">Restricted and non-restricted API calls</li><li name="0db8" class="graf graf--li graf-after--li">Platform wise behavior</li><li name="2e27" class="graf graf--li graf-after--li">Behavior for each library / plugin</li><li name="619c" class="graf graf--li graf-after--li">Behavior for each method type i.e. GET, POST, PUT, DELETE</li></ul><p name="cdd1" class="graf graf--p graf-after--li">and finally overlap the results to see which library is best for our usage.</p><p name="acea" class="graf graf--p graf-after--p"><strong class="markup--strong markup--p-strong">Note</strong>: The behavior of GET, POST, PUT, DELETE methods for a particular set of variables remain same in all cases. In other words, if one fails, all will fails, if one succeeds, all will.</p><h3 name="0900" class="graf graf--h3 graf-after--p">Running the&nbsp;app</h3><p name="5f6c" class="graf graf--p graf-after--h3">Once you install the required libraries for a particular option (We will see how to install each library in individual sections), you can simply run the app with following options&nbsp;:</p><h4 name="a849" class="graf graf--h4 graf-after--p">Web</h4><p name="45ac" class="graf graf--p graf-after--h4">For web testing, you can simply run the app with</p><pre name="1e01" class="graf graf--pre graf-after--p">$ ionic serve</pre><h4 name="14d5" class="graf graf--h4 graf-after--pre">Android /&nbsp;iOS</h4><p name="04b6" class="graf graf--p graf-after--h4">For Android and iOS, you will have to build the app&nbsp;, open the corresponding native IDE and build the app. Here are the steps</p><pre name="b730" class="graf graf--pre graf-after--p"><strong class="markup--strong markup--pre-strong">// Create platform</strong><br>$ npx cap add android // replace `android` with `ios` for iOS</pre><pre name="dc05" class="graf graf--pre graf-after--pre"><strong class="markup--strong markup--pre-strong">// Build app</strong><br>$ ionic build // replace `android` with `ios` for iOS</pre><pre name="b464" class="graf graf--pre graf-after--pre"><strong class="markup--strong markup--pre-strong">// Sync data with native app </strong><br>$ npx cap sync // replace `android` with `ios` for iOS</pre><pre name="cd2a" class="graf graf--pre graf-after--pre"><strong class="markup--strong markup--pre-strong">// Open native IDE to build app</strong><br>$ npx cap open android // replace `android` with `ios` for iOS</pre><p name="3843" class="graf graf--p graf-after--pre">After every change in the app, you need to run <code class="markup--code markup--p-code">ionic build</code> and <code class="markup--code markup--p-code">npx cap copy</code> to reflect changes in Android /iOS build.</p><p name="44fb" class="graf graf--p graf-after--p">Let’s start with the libraries/plugins one by one</p><h3 name="53e9" class="graf graf--h3 graf-after--p">1. Fetch&nbsp;API</h3><p name="e0a6" class="graf graf--p graf-after--h3">Let’s start with web default Fetch API. You don’t need to setup anything to use Fetch. It’s the default for JS.</p><p name="380f" class="graf graf--p graf-after--p">Here’s the sample code for the unrestricted set of methods (the restricted set will be exact same, with only change in API method name). Here’s how the code looks</p><figure tabindex="0" contenteditable="false" name="f1f5" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 361.143%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/e5a7be4641c4a79f62b1364852c904af.js %}</div></div></figure><p name="c956" class="graf graf--p graf-after--figure">Ignore the variables and <code class="markup--code markup--p-code">changeStatus</code> method. These are only for displaying the ❌ and ✅ in the UI for better visualization of results.</p><p name="1c2a" class="graf graf--p graf-after--p">For Fetch API, here’s the overall result for Web, Android and iOS</p><figure tabindex="0" contenteditable="false" name="edbb" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 277px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 216.6%;"></div><img class="graf-image" data-image-id="1*Fcc4-UkTDAecXiRC1XmpNQ.png" data-width="277" data-height="600" alt="Ionic Capacitor API call results&hairsp;—&hairsp;Fetch API" src="https://cdn-images-1.medium.com/max/800/1*Fcc4-UkTDAecXiRC1XmpNQ.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic Capacitor API call results&hairsp;—&hairsp;Fetch&nbsp;API</figcaption></figure><h3 name="66d6" class="graf graf--h3 graf-after--figure">2. Angular HttpClient</h3><p name="c990" class="graf graf--p graf-after--h3">Angular <code class="markup--code markup--p-code">HttpClient</code> comes with Angular setup in form of the <code class="markup--code markup--p-code">@angular/common/http</code> package. It can be imported in any&nbsp;<code class="markup--code markup--p-code">.ts</code> file and used as http client. Just add this in the page’s <code class="markup--code markup--p-code">module.ts</code> file</p><pre name="5cf6" class="graf graf--pre graf-after--p">import { HttpClientModule } from '@angular/common/http';</pre><pre name="f9a0" class="graf graf--pre graf-after--pre">....<br> @NgModule({<br>  ...<br>  imports: [HttpClientModule],<br>  providers:[..]<br>})</pre><p name="923a" class="graf graf--p graf-after--pre">Here’s how the code looks for HttpClient</p><figure tabindex="0" contenteditable="false" name="edd9" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 263.714%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/589df4ed5516e722259859ecbea8ad9f.js %}</div></div></figure><p name="e7ac" class="graf graf--p graf-after--figure">For Angular HttpClient, here’s the overall result for Web, Android and iOS</p><figure tabindex="0" contenteditable="false" name="98f7" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 277px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 216.6%;"></div><img class="graf-image" data-image-id="1*1XKJDrc0M_n1E7UlDLTCXg.png" data-width="277" data-height="600" alt="Ionic Capacitor API call results&hairsp;—&hairsp;Angular HttpClient" src="https://cdn-images-1.medium.com/max/800/1*1XKJDrc0M_n1E7UlDLTCXg.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic Capacitor API call results&hairsp;—&hairsp;Angular HttpClient</figcaption></figure><h3 name="8008" class="graf graf--h3 graf-after--figure">3. Ionic Native Http Plugin (Cordova)</h3><p name="4744" class="graf graf--p graf-after--h3">Install the Ionic Native Http Plugin by running</p><pre name="1249" class="graf graf--pre graf-after--p">$ npm install cordova-plugin-advanced-http<br>$ npm install @ionic-native/http</pre><p name="774d" class="graf graf--p graf-after--pre">Also, in the page’s <code class="markup--code markup--p-code">module.ts</code> file&nbsp;, add</p><pre name="0e67" class="graf graf--pre graf-after--p">import { HTTP } from '@ionic-native/http/ngx';<br>....<br> @NgModule({<br>  ...<br>  imports: [...],<br>  providers:[HTTP]<br>})</pre><p name="b89f" class="graf graf--p graf-after--pre">Since this is a Cordova plugin, it will not work on Web. But note that we can use this plugin in a Capacitor app, as Capacitor supports Cordova plugins.</p><p name="b36c" class="graf graf--p graf-after--p">Also post install, you’ll have to run <code class="markup--code markup--p-code">npx cap sync</code> for Android and iOS. Here’s how to code looks for this plugin</p><figure tabindex="0" contenteditable="false" name="a905" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 288.857%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/06890816432aeea849b5f7388f53cb00.js %}</div></div></figure><p name="ce1d" class="graf graf--p graf-after--figure">For Ionic Native Http, here’s the overall result for Web, Android and iOS</p><figure tabindex="0" contenteditable="false" name="6cd1" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 277px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 216.6%;"></div><img class="graf-image" data-image-id="1*aO1AWX4TInuCyCgCIzmFKA.png" data-width="277" data-height="600" src="https://cdn-images-1.medium.com/max/800/1*aO1AWX4TInuCyCgCIzmFKA.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic Capacitor API call results&hairsp;—&hairsp;Ionic Native&nbsp;Http</figcaption></figure><h3 name="c070" class="graf graf--h3 graf-after--figure">4. Ionic Native Http connection backend</h3><p name="552a" class="graf graf--p graf-after--h3">For this options, you’ll need another plugin which combines the power of <code class="markup--code markup--p-code">httpClient</code> and Ionic Native Http plugin. Install this plugin using</p><pre name="9311" class="graf graf--pre graf-after--p">$ npm install --save ionic-native-http-connection-backend</pre><pre name="a8e8" class="graf graf--pre graf-after--pre">// In some cases, it might ask to install a dependency cordova-plugin-file</pre><pre name="ca6c" class="graf graf--pre graf-after--pre">$ npm install cordova-plugin-file<br>$ npm install @ionic-native/file</pre><p name="df5a" class="graf graf--p graf-after--pre">Again note that we can use this plugin in a Capacitor app, as Capacitor supports Cordova plugins.</p><p name="3294" class="graf graf--p graf-after--p">You’ll need to take few extra measures here:</p><ul class="postList"><li name="9e48" class="graf graf--li graf-after--p">Add <code class="markup--code markup--li-code">NativeHttpModule</code>, <code class="markup--code markup--li-code">NativeHttpBackend</code> and <code class="markup--code markup--li-code">NativeHttpFallback</code> into the module where you are using the plugins. If you plan to use it throughout the app, add these in <code class="markup--code markup--li-code">app.module.ts</code></li></ul><figure tabindex="0" contenteditable="false" name="f347" class="graf graf--figure graf--iframe graf-after--li is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 65.714%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/5e4dd5b6d76e378724ec0bdaceddb61b.js %}</div></div></figure><p name="38c7" class="graf graf--p graf-after--figure">Here’s how the code will look for calling APIs using this module</p><figure tabindex="0" contenteditable="false" name="33e3" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 270%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/42f326ea332a7e2d02cb3753ec5f7340.js %}</div></div></figure><p name="93cf" class="graf graf--p graf-after--figure">Notice we haven’t added <code class="markup--code markup--p-code">import { HTTP } from ‘@ionic-native/http/ngx’;</code> in this page, but that is automatically attached to API calls when run on device.</p><p name="2d3f" class="graf graf--p graf-after--p">For Ionic Native Advanced Http, here’s the overall result for Web, Android and iOS</p><figure tabindex="0" contenteditable="false" name="24a9" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 277px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 216.6%;"></div><img class="graf-image" data-image-id="1*H6qJaWEIX6DP2XYsgmQbEQ.png" data-width="277" data-height="600" src="https://cdn-images-1.medium.com/max/800/1*H6qJaWEIX6DP2XYsgmQbEQ.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic Capacitor API call results&hairsp;—&hairsp;Ionic Native Advanced&nbsp;Http</figcaption></figure><h3 name="a670" class="graf graf--h3 graf-after--figure">5. Capacitor Http</h3><p name="55ed" class="graf graf--p graf-after--h3">This plugin will run only in a Capacitor app. Install the plugin using</p><pre name="a8cf" class="graf graf--pre graf-after--p">$ npm install @capacitor-community/http</pre><p name="566c" class="graf graf--p graf-after--pre">No additional configuration required for Android and iOS. You can use it in the page as</p><figure tabindex="0" contenteditable="false" name="b0b6" class="graf graf--figure graf--iframe graf-after--p is-defaultValue"><div class="aspectRatioPlaceholder is-locked"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 373.714%;"></div><div class="iframeContainer">{% gist https://gist.github.com/enappd/42537dd75f4217d936ca4d017883a19f.js %}</div></div></figure><p name="1f00" class="graf graf--p graf-after--figure">For Capacitor Http, here’s the overall result for Web, Android and iOS</p><figure tabindex="0" contenteditable="false" name="d0a9" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 277px; max-height: 600px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 216.6%;"></div><img class="graf-image" data-image-id="1*JHs2GgYW2dwBLUxULP1IaQ.png" data-width="277" data-height="600" src="https://cdn-images-1.medium.com/max/800/1*JHs2GgYW2dwBLUxULP1IaQ.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic Capacitor API call results&hairsp;—&hairsp;Capacitor Http</figcaption></figure><h3 name="ff8c" class="graf graf--h3 graf-after--figure">Conclusion</h3><p name="6259" class="graf graf--p graf-after--h3">We saw several options to call APIs in an Ionic Capacitor Angular app. We saw how the plugin can behave differently in Web vs Android/iOS environment, and also if the server is allowing all origins or not.</p><p name="3d67" class="graf graf--p graf-after--p">Here’s a gist of which library to use when</p><ul class="postList"><li name="a2d0" class="graf graf--li graf-after--p"><strong class="markup--strong markup--li-strong">Fetch</strong>&hairsp;—&hairsp;Use it when you are making an app where you can control the server <code class="markup--code markup--li-code">Allow-origin</code> behavior. You can sent the server to accept your app’s origins, and then Fetch will work for all scenarios</li><li name="249d" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Angular HttpClient</strong>&hairsp;—&hairsp;Same as Fetch</li><li name="64ce" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Ionic Native Http</strong>&hairsp;—&hairsp;Can by-pass allow-origin restriction on Android/iOS device. But it cannot run on web, so development is difficult</li><li name="1014" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Ionic Native Advanced Http</strong>&hairsp;—&hairsp;This allows you to run the APIs in web, android and iOS, but still cannot run origin restricted APIs on web</li><li name="1ea5" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Capacitor Http&hairsp;</strong>—&hairsp;This allows you to run the APIs in web, android and iOS, but still cannot run origin restricted APIs on web</li></ul><p name="901d" class="graf graf--p graf-after--li">In conclusion, <strong class="markup--strong markup--p-strong">Capacitor Http</strong> and <strong class="markup--strong markup--p-strong">Ionic Native Advanced Http</strong> plugins will provide the same level of functionality for Ionic apps. Only difference being the nature of build environment —</p><ul class="postList"><li name="20c9" class="graf graf--li graf-after--p">While <strong class="markup--strong markup--li-strong">Ionic Native Advanced Http</strong> can run both in Cordova and Capacitor apps, <strong class="markup--strong markup--li-strong">Capacitor Http</strong> runs only in Capacitor environment</li><li name="4707" class="graf graf--li graf-after--li">While <strong class="markup--strong markup--li-strong">Capacitor Http </strong>can run on Ionic-Angular, Ionic-React and Ionic Vue frameworks, <strong class="markup--strong markup--li-strong">Ionic Native Advanced Http Ionic Native Advanced Http </strong>can be used only in Ionic-Angular</li></ul><p name="fd26" class="graf graf--p graf-after--li">So in essence it’s a tie&nbsp;! 🤜 🤛 I personally like Capacitor Http, as it is just one plugin to be installed instead of 4 packages in Ionic Native Advanced case.</p><p name="b0a3" class="graf graf--p graf-after--p graf--trailing">Hope this post will clarify few of your Http call doubts.</p></div></div></section><section name="0862" class="section section--body"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><h3 name="c190" class="graf graf--h3 graf--leading">Next Steps</h3><p name="ee74" class="graf graf--p graf-after--h3 graf--trailing">If you liked this blog, you will also find the following blogs interesting and helpful. Feel free to ask any questions in the comment section</p></div></div></section><section name="06ac" class="section section--body"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><h3 name="bdf7" class="graf graf--h3 graf--leading">Ionic Capacitor</h3><ul class="postList"><li name="5f8e" class="graf graf--li graf-after--h3"><strong class="markup--strong markup--li-strong">Basic</strong>&hairsp;—&hairsp;<a href="https://enappd.com/blog/use-geolocation-geocoding-and-reverse-geocoding-in-ionic-capacitor/131"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Geolocation</a> | <a href="https://enappd.com/blog/qr-code-and-barcode-scanning-with-ionic-capacitor/127"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Barcode &amp; QR code</a> | <a href="https://enappd.com/blog/facebook-login-in-capacitor-apps-with-ionic-angular/128"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Facebook Login</a> (Angular) | <a href="https://enappd.com/blog/facebook-login-in-ionic-react-capacitor-apps/118"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Facebook Login (React)</a> | <a href="https://enappd.com/blog/icon-splash-in-ionic-react-capacitor-apps/114"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Icon and Splash</a> | <a href="https://enappd.com/blog/camera-and-gallery-in-ionic-react-app-using-capacitor/110"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Camera &amp; Photo Gallery</a> | <a href="https://enappd.com/blog/debugging-ionic-apps-using-chrome-and-safari-developers-tools/167"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Debugging with browser</a>|<a href="https://enappd.com/blog/make-awesome-theme-switcher-in-ionic-5/170"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Theming in Ionic apps</a> | <a href="https://enappd.com/blog/google-login-in-ionic-capacitor-app-with-angular/178/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Google Login (Angular)</a></li><li name="0f51" class="graf graf--li graf-after--li"><strong class="markup--strong markup--li-strong">Advanced</strong>&hairsp;—&hairsp;<a href="https://enappd.com/blog/implement-admob-in-ionic-react-capacitor-apps/135"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">AdMob</a> | <a href="https://enappd.com/blog/local-notifications-in-ionic-5-capacitor/132"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Local Notifications</a> | <a href="https://enappd.com/blog/google-login-in-ionic-react-capacitor-apps/122"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Google Login</a> | <a href="https://enappd.com/blog/twitter-login-in-ionic-react-capacitor-app/121"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Twitter Login</a> | <a href="https://enappd.com/blog/html5-games-in-ionic-capacitor-using-phaser/115"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Games using Phaser</a> | <a href="https://enappd.com/blog/play-music-in-ionic-capacitor-apps/112"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Play music</a> | <a href="https://enappd.com/blog/firebase-push-notification-in-ionic-react-capacitor/111"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Push Notifications</a></li></ul><h3 name="da78" class="graf graf--h3 graf-after--li">Ionic Cordova</h3><ul class="postList"><li name="23b7" class="graf graf--li graf-after--h3"><a href="https://enappd.com/blog/ionic-app-with-nodejs-express-mysql-sequelize-taxi-app/160"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Taxi Booking App example with Ionic, Node, Express and MySQL</a></li><li name="e3ed" class="graf graf--li graf-after--li">Ionic Payment Gateways&hairsp;—&hairsp;<a href="https://enappd.com/blog/integrate-stripe-payment-gateway-in-ionic-5-apps-and-pwa-using-firebase/158"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Stripe with Firebase</a> | <a href="https://enappd.com/blog/ionic-5-stripe-payment-integration-firebase-cloud-functions-vs-node-express-based-server/159"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Stripe with NodeJS</a> | <a href="https://enappd.com/blog/paypal-integration-in-ionic-apps-and-pwa/142"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">PayPal</a> |<a href="https://enappd.com/blog/paypal-payment-integration-using-braintree-in-ionic-5-apps/177/"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">PayPal with Braintree</a>| <a href="https://enappd.com/blog/how-to-integrate-apple-pay-in-ionic-4-apps/21"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Apple Pay</a> | <a href="https://enappd.com/blog/how-to-integrate-razorpay-in-ionic-4-apps-and-pwa/20"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">RazorPay</a></li><li name="4ecb" class="graf graf--li graf-after--li">Ionic Charts with&hairsp;—&hairsp;<a href="https://enappd.com/blog/ionic-4-charts-using-google-charts/66"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Google Charts </a>| <a href="https://enappd.com/blog/adding-charts-in-ionic-4-apps-and-pwa-part-3/60"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">HighCharts</a> | <a href="https://enappd.com/blog/adding-charts-in-ionic-4-apps-and-pwa-part-2/54"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">d3.js</a> | <a href="https://enappd.com/blog/charts-in-ionic-4-apps-and-pwa-part-1/52"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Chart.js</a></li><li name="7dc9" class="graf graf--li graf-after--li">Ionic Authentications&hairsp;—&hairsp;<a href="https://enappd.com/blog/firebase-email-authentication-in-ionic-apps/153"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Via Email</a> | <a href="https://enappd.com/blog/implement-anonymous-login-in-ionic-apps-with-firebase/154"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Anonymous</a> | <a href="https://enappd.com/blog/facebook-login-in-ionic-apps-using-firebase/150"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Facebook</a> | <a href="https://enappd.com/blog/implement-google-login-in-ionic-apps-using-firebase/147"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Google</a> | <a href="https://enappd.com/blog/twitter-login-in-ionic-4-apps-using-firebase/24"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Twitter</a> | <a href="https://enappd.com/blog/firebase-phone-authentication-in-ionic-5-apps/169"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Via Phone</a></li><li name="1310" class="graf graf--li graf-after--li">Ionic Features&hairsp;—&hairsp;<a href="https://enappd.com/blog/ionic-5-complete-guide-on-geolocation/141"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Geolocation</a>| <a href="https://enappd.com/blog/ionic-complete-guide-barcode-qrcode-scan/140"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">QR Code reader</a> | <a href="https://enappd.com/blog/best-fitness-plugins-for-ionic-4-how-to-use-pedometer/15"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Pedometer</a>| <a href="https://enappd.com/blog/implement-signature-pad-in-ionic-apps/145"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Signature</a> <a href="https://enappd.com/blog/implement-signature-pad-in-ionic-apps/145"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Pad</a> | <a href="https://enappd.com/blog/using-background-geolocation-in-ionic-angular-apps/165"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Background Geolocation</a> | <a href="https://enappd.com/blog/detect-wifi-and-data-network-in-ionic-5-apps/173"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Network Detection</a></li><li name="5a5f" class="graf graf--li graf-after--li">Media in Ionic&hairsp;—&hairsp;<a href="https://enappd.com/blog/spotify-like-music-in-ionic-4-apps/48"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Audio</a> | <a href="https://enappd.com/blog/adding-video-player-in-ionic-4-app/64"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Video</a> | <a href="https://enappd.com/blog/camera-and-image-picker-in-ionic-apps/148"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Image Picker</a> | <a href="https://enappd.com/blog/how-to-add-image-cropper-in-ionic-apps/149"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Image Cropper</a> | <a href="https://enappd.com/blog/implement-sounds-and-vibration-in-ionic-apps/172"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Sounds and Vibrations</a></li><li name="71f9" class="graf graf--li graf-after--li">Ionic Essentials&hairsp;—&hairsp;<a href="https://enappd.com/blog/debugging-ionic-apps-using-chrome-and-safari-developers-tools/167"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Debugging with browser</a>| <a href="https://enappd.com/blog/ionic-4-save-and-retrieve-data-locally-on-device/59"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Native Storage</a> | <a href="https://enappd.com/blog/how-to-translate-in-ionic-internationalization-and-localization/143"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Translations</a> | <a href="https://enappd.com/blog/how-to-use-rtl-right-to-left-in-ionic-apps-pwa/152"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">RTL</a> | <a href="https://enappd.com/blog/using-sentry-error-monitoring-with-ionic-angular-applications/164"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Sentry Error Monitoring</a> | <a href="https://enappd.com/blog/social-sharing-component-in-ionic-5-mobile-web-apps/168"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Social sharing</a> | <a href="https://enappd.com/blog/how-to-generate-and-download-pdf-in-ionic-apps/174"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">PDF generation</a></li><li name="58ce" class="graf graf--li graf-after--li">Ionic messaging&hairsp;—&hairsp;<a href="https://enappd.com/blog/how-to-implement-firebase-push-notifications-in-ionic-apps/157"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Firebase Push</a> | <a href="https://enappd.com/blog/how-to-automatically-read-sms-in-ionic-5-apps/175"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Reading SMS</a> | <a href="https://enappd.com/blog/local-notifications-in-ionic-5-capacitor/132"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Local Notifications</a></li><li name="0b6b" class="graf graf--li graf-after--li">Ionic with Firebase&hairsp;—&hairsp;<a href="https://enappd.com/blog/how-to-integrate-firebase-in-ionic-4-apps/23"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Basics</a> | <a href="https://enappd.com/blog/firebase-with-ionic-4-hosting-auth-and-db-connection/58"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Hosting and DB</a> | <a href="https://enappd.com/blog/firebase-cloud-functions-in-ionic-5-complete-guide/166"  class="markup--anchor markup--li-anchor" rel="noopener"    target="_blank">Cloud functions</a> | <a href="https://enappd.com/blog/github-actions-deploying-ionic-angular-app-to-firebase-hosting/146"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Deploy App to Firebase</a> | <a href="https://enappd.com/blog/how-to-use-firebase-emulators-with-ionic-angular-applications/163"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Firebase simulator</a></li><li name="eaef" class="graf graf--li graf-after--li graf--trailing">Unit Testing in Ionic&hairsp;—&hairsp;<a href="https://enappd.com/blog/beginners-guide-to-ionic-angular-unit-testing-part-1/151"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Part 1</a> | <a href="https://enappd.com/blog/beginners-guide-to-ionic-angular-unit-testing-part-2-mocks-and-spies/155"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Mocks &amp; Spies</a>| <a href="https://enappd.com/blog/beginners-guide-to-ionic-angular-unit-testing-async-testing/156"  class="markup--anchor markup--li-anchor" rel="noopener nofollow noopener noopener noopener"    target="_blank">Async Testing</a></li></ul></div></div></section><section name="5071" class="section section--body section--last"><div class="section-divider"><hr class="section-divider"></div><div class="section-content"><div class="section-inner sectionLayout--insetColumn"><h3 name="4c3b" class="graf graf--h3 graf--leading">Ionic Capacitor Full App (Angular)</h3><p name="9a60" class="graf graf--p graf-after--h3">If you need a base to start your next Angular <strong class="markup--strong markup--p-strong">Capacitor app</strong>, you can make your next awesome app using <a href="https://store.enappd.com/product/capacitor-full-app-with-ionic-angular/"  class="markup--anchor markup--p-anchor" rel="noopener nofollow noopener noopener noopener noopener"    target="_blank">Capacitor Full App</a></p><figure tabindex="0" contenteditable="false" name="d02c" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 700px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 100%;"></div><img class="graf-image" data-image-id="1*fed8vWeCTOvkNBLbFxsvDw.png" data-width="2748" data-height="2748" src="https://cdn-images-1.medium.com/max/800/1*fed8vWeCTOvkNBLbFxsvDw.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Capacitor Full App with huge number of layouts and&nbsp;features</figcaption></figure><h3 name="ad14" class="graf graf--h3 graf-after--figure">Ionic Capacitor Full App&nbsp;(React)</h3><p name="4fa5" class="graf graf--p graf-after--h3">If you need a base to start your next Ionic 5 React Capacitor app, you can make your next awesome app using <a href="https://store.enappd.com/product/ionic-react-full-app-capacitor/"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic 5 React Full App in Capacitor</a></p><figure tabindex="0" contenteditable="false" name="0d2d" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 441px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 63%;"></div><img class="graf-image" data-image-id="1*G3yOFVX4oABx9MhUy-3kng.png" data-width="760" data-height="479" alt="Ionic 5 React Full App in Capacitor from Enappd" src="https://cdn-images-1.medium.com/max/800/1*G3yOFVX4oABx9MhUy-3kng.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic 5 React Full App in Capacitor from&nbsp;Enappd</figcaption></figure><h3 name="30ba" class="graf graf--h3 graf-after--figure">Ionic Cordova Full App (Angular)</h3><p name="1008" class="graf graf--p graf-after--h3">If you need a base to start your next Ionic 5 app, you can make your next awesome app using <a href="https://store.enappd.com/product/ionic-full-app"  class="markup--anchor markup--p-anchor" rel="noopener"    target="_blank">Ionic 5 Full App</a></p><figure tabindex="0" contenteditable="false" name="e911" class="graf graf--figure graf-after--p"><div class="aspectRatioPlaceholder is-locked" style="max-width: 700px; max-height: 442px;"><div class="aspectRatioPlaceholder-fill" style="padding-bottom: 63.2%;"></div><img class="graf-image" data-image-id="1*RAe0nXh5ymkCfxGqSqdE-A.png" data-width="760" data-height="480" src="https://cdn-images-1.medium.com/max/800/1*RAe0nXh5ymkCfxGqSqdE-A.png"><div class="crosshair u-ignoreBlock"></div></div><figcaption class="imageCaption" contenteditable="true" data-default-value="Type caption for image (optional)">Ionic Full App in Cordova, with huge number of layouts and&nbsp;features</figcaption></figure><p name="444a" class="graf graf--p graf--empty graf-after--figure graf--trailing"><br></p></div></div></section></div></article></main>