What is the best way to replace HttpClient in Aurelia?

I am completely new to Aurelia.

How can I modify the code below in order to implement a dummy HttpClient, such as a json reader, that will provide a static set of json data without the need for a server during development?

import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';

@inject(HttpClient)
export class Users {
  heading = 'Sample Users';
  users = [];

  constructor(http) {
    http.configure(config => {
      config
        .useStandardConfiguration()
        .withBaseUrl('https://api.github.com/');
    });

    this.http = http;
  }

  activate() {
    // Instead of fetching real data from 'users', we can change it to fetch static JSON data here
    return Promise.resolve([{ name: 'John Doe', age: 30 }, { name: 'Jane Smith', age: 25 }])
      .then(users => this.users = users);
  }
}

Answer №1

To adapt the demo code in your initial post for substituting HttpClient implementations, there are a few steps to follow.

Step 1

Firstly, remove the configuration code from the class constructor...

The lines to be removed from users.js:

...
http.configure(config => {
  config
    .useStandardConfiguration()
    .withBaseUrl('https://api.github.com/');
});
...

These lines should be relocated to the main.js file:

main.js

export function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();

  configureContainer(aurelia.container); 

  aurelia.start().then(a => a.setRoot());
}

function configureContainer(container) {
  let http = new HttpClient();
  http.configure(config => {
    config
      .useStandardConfiguration()
      .withBaseUrl('https://api.github.com/');
  });
  container.registerInstance(HttpClient, http);
}

Once this adjustment is made, the contents of users.js should appear as follows:

users.js

import {inject} from 'aurelia-framework';
import {HttpClient} from 'aurelia-fetch-client';

@inject(HttpClient)
export class Users {
  heading = 'Github Users';
  users = [];

  constructor(http) {
    this.http = http;
  }

  activate() {
    return this.http.fetch('users')
      .then(response => response.json())
      .then(users => this.users = users);
  }
}

Step 2:

Create a mock for the HttpClient.

The user.js module relies solely on the fetch method which returns a Response object featuring a json method. Below is a basic mock setup:

let mockUsers = [...todo: create mock user data...];

let httpMock = {
  fetch: url => Promise.resolve({
    json: () => mockUsers
  })
};

Step 3:

Adjust the container to utilize the http mock:

In step 1, we introduced a configureContainer function within the main.js module that registered a configured HttpClient instance into the container. To switch to our mock version, modify the configureContainer function as illustrated below:

main.js

...

let mockUsers = [...todo: create mock user data...];

let httpMock = {
  fetch: url => Promise.resolve({
    json: () => mockUsers
  })
};

function configureContainer(container) {      
  container.registerInstance(HttpClient, httpMock);
}

Further information on configuring the container can be found here: https://github.com/aurelia/dependency-injection/issues/73

Answer №2

An alternative approach to providing static data for application development is by utilizing Navigation Skeleton with Gulp and BrowserSync to simulate API calls.

For example, if you are loading JSON data from a virtual directory like /api, you can fake the API call:

GET /api/products

To achieve this, you only need to do two things:

Store mock data in files

Create an /api folder in the root directory of your Aurelia app.

In the /api/products subfolder, create a new file named GET.json containing the desired JSON structure, such as:

GET.json

[ { "id": 1, "name": "Keyboard", "price": "60$" },
  { "id": 2, "name": "Mouse", "price": "20$" },
  { "id": 3, "name": "Headphones", "price": "80$" }
]

Configure BrowserSync to simulate API calls

Edit the serve.js file located in the /build/tasks folder. Update the serve task definition with the following code:

gulp.task('serve', ['build'], function(done) {
  browserSync({
    online: false,
    open: false,
    port: 9000,
    server: {
      baseDir: ['.'],
      middleware: function(req, res, next) {
        res.setHeader('Access-Control-Allow-Origin', '*');

        // Simulate API calls
        if (req.url.indexOf('/api/') > -1) {
          console.log('[serve] responding ' + req.method + ' ' + req.originalUrl);

          var jsonResponseUri = req._parsedUrl.pathname + '/' + req.method + '.json';

          var jsonResponse = require('../..' + jsonResponseUri);

          req.url = jsonResponseUri;
          req.method = 'GET';
        }

        next();
      }
    }
  }, done);
});

Upon running gulp serve, BrowserSync will emulate the API calls by serving data from static files on disk.

For a practical example, visit my GitHub repository. More insights can be found in my article on Mocking API calls in Aurelia.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing Firebase Cloud Messaging for push notifications in Twilio Conversations

I am currently facing a challenge in setting up push notifications using Twilio Conversations and Firebase Cloud Messaging on a Next.js 12 app. The documentation assumes the use of Firebase 8 syntax, but I am working with Firebase 9 in this case. I have be ...

Managing and updating arrays in VueJS2: Conditionally push new items and update only if their properties have changed

I am currently facing an issue with my form where each time a user updates a value in an input field, a new array element is created and added to the form results. I'm looking for a way to update the properties of the existing array element without cr ...

Validation of 'e' Symbol in Input Type Number Using jQuery Validator

Hey everyone, I'm currently utilizing jQuery validator for an input field with the type of number. However, when I enter 1e1, it shows an error message saying "invalid number." Is there a way to allow numbers like 1e1 (which equals 10) without trigger ...

Here is a way to retrieve the name of a ref object stored in an array using Vue.js 3 and Typescript

I have a Form, with various fields that I want to get the value of using v-model and assign them to ref objects. In order to populate my FormData object with this data, I require both the name and the value of the ref objects. Unfortunately, I am struggli ...

Maintain component state in a React app when the page is re

After navigating to a specific page by passing props, I need the ability to reload the page without losing its state. Currently, when I try to refresh the page, an error is thrown indicating that the prop is missing. For instance, if I use history.push({ ...

A guide on incorporating oAuth 2.0 into Tizen

Currently, I am in the process of incorporating Google authentication using oAuth 2.0 in Tizen. I am following the guidelines provided here. Despite successfully obtaining the user code as instructed in the link, I keep receiving an invalid request error w ...

How to Modify the Data in a Dynamic Object within the Vuex Store in a Nuxt Application

Within my Vue/Nuxt project, I have implemented a form where users can add and update dynamic fields for calculating price offers. Upon loading the form, one field is created using the beforeMount lifecycle, with the option for users to add more fields as n ...

How can I extract values from an array stored in an external text file using Jquery?

I'm attempting to retrieve an error message from an external file called errors.txt. The contents of errors.txt are as follows: var data = { 'errors': [{ "code": "9999", "message": { row: 1, ...

JavaScript that Implements MVC Architecture Using C#

When working on a cshtml page within my View, I am able to easily retrieve the URL to an action using this line of code: <h1>@Url.Action("NewComment", "Case")</h1> If I include the same code in JavaScript like this: <script> alert( ...

Update the network name in the Axios request

Currently, I am utilizing Axios for handling both GET and POST requests. One question that has been on my mind is how to modify the network name: At present, the name serves as the parameter accompanying each request. However, I ponder whether it's f ...

How to determine the presence of 'document' in Typecsript and NextJS

Incorporating NextJS means some server-side code rendering, which I can manage. However, I'm facing a challenge when trying to check for set cookies. I attempted: !!document && !!document.cookie as well as document !== undefined && ...

Enhance your webpage's body by zooming in using jQuery on Mozilla Firefox

I have a webpage and I would like to zoom its body when it loads using jQuery. However, the CSS zoom feature is not working in Mozilla Firefox. This is what I currently am using: $("body").css("zoom", "1.05"); It worked in Chrome, Opera, and Edge, but un ...

The latest version of Material UI icons caused compatibility issues with React-Select

I recently made the switch from using @material-ui/icons version 4.11.2 to @mui/material and @mui/icons-material version 5.2.3 Although material UI is not directly integrated with react-select, there seems to be some interaction happening. The transition ...

Encountering a JS_Parse_Error error while trying to update the TypeScript target to ES6 using aurelia-b

I encountered an issue that is causing difficulties in utilizing async/await or yield/generators. Initially, I utilized the aurelia skeleton for typescript & asp5 (aspnetcore) with the default target set to es5. To incorporate async/await in my TypeScript ...

What is the best way to load the nested array attributes in an HTML table dynamically with AngularJS?

I attempted the following code, but I am only able to access values for cardno and cardtype. Why can't I access the others? Any suggestions? <tr ng-repeat="data in myData17.layouts"> <td ng-show="$index==1">{{data.name}}</td> &l ...

document ready function in the Microsoft AJAX client side library

The Microsoft AJAX client-side library contains various functions that imitate the server-side Page Life Cycle and conditions like if (!Page.IsPostBack). I am unsure about which client-side function corresponds to the equivalent server-side method. What is ...

What is the process for loading this image?

While browsing through this stunning website, I came across a feature that caught my eye. Can someone please explain how the designer displayed the "The magic is loading" effect: The image vanishes once the site has finished loading completely. ...

Adding a button to a shadow root that already exists is not the proper procedure

var shadow = document.getElementById( "3rd-party-div" ).shadowRoot; let style = document.createElement("style"); style.textContent = ` .custom_button{ padding: 10px; display:block; float:left; text-ali ...

Tips for optimizing the processing speed of large XML files using jQuery, Javascript, and PHP

Currently, I am developing a store overview page that displays about 20 products per page. The data for this page is sourced from a zipped (gzip) XML file (*.xml.gz). You can find the feed here: . Every day, I download this file to my server using PHP and ...

Steps for rearranging the order of CSS grid layout

Could you assist me in implementing a grid layout that fulfills these specific criteria? I'm unsure of how to proceed, so any guidance would be greatly appreciated. When there are more than 9 items, the current layout changes the order from top to bo ...