Angular2 waits for the JSON file to be fully loaded before proceeding

At the moment, I am loading a JSON file in the following way:

translation.service.ts

@Injectable()
export class TranslationService {

    private _messages = [];

    constructor(private _http: Http) {
        var observable = this._http.get("/app/i18n/localizable.it.strings").map((res: Response) => res.json());
        observable.subscribe(res => {
            this._messages = res;
        });
    }

    getTranslationByKey(key: string, args?: any[]) {
        return this._messages[key];
    }
}

localizable.it.strings

{
    "home.nav.calendar": "Calendar",
    ...
}

My TranslationService is injected into my HomeComponent, but the issue arises when trying to access these values through a pipe before they are fully loaded during page rendering.

translate.pipe.ts

@Pipe({name: 'translate'})
export class TranslatePipe implements PipeTransform {

    constructor(private _translation: TranslationService) {}

    transform(value: string, args: string[]) : any {
        return this._translation.getTranslationByKey(value);
    }
}

Is there a solution to load all values from a JSON file prior to any page being rendered?

Answer №1

To enhance your service and streamline data handling, consider incorporating a mechanism to detect when data is ready or loaded automatically.

Start by introducing an observable that alerts when the data has been loaded into your service:

@Injectable()
export class TranslationService {

  private _messages = {};

  private translationLoaded : Observable<boolean>;
  private translationLoadedObserver : Observer<boolean>;

  constructor(private _http: Http) {
    this.translationLoaded = Observable.create((observer) => {
      this.translationLoadedObserver = observer;
    });

    var observable = this._http.get("app/i18n/localizable.it.strings").map((res: Response) => res.json());
    observable.subscribe(res => {
      this._messages = res;
      this.translationLoadedObserver.next(true);
    });
  }

  getTranslationByKey(key: string, args?: any[]) {
    return this._messages[key];
  }
}

The pipe can then subscribe to this observable to seamlessly update the message value similar to how the async function works:

@Pipe({
  name: 'translate',
  pure: false  // required to update the value when data are loaded
})
export class TranslatePipe implements PipeTransform {
  constructor(private _ref :ChangeDetectorRef, private _translation: TranslationService) {
    this.loaded = false;
  }

  transform(value: string, args: string[]) : any {
    this.translationLoadedSub = this._translation.translationLoaded.subscribe((data) => {
      this.value = this._translation.getTranslationByKey(value);
      this._ref.markForCheck();
      this.loaded = true;
    });

    if (this.value == null && this.loaded) {
      this.value = this._translation.getTranslationByKey(value);
    }
    return this.value;
  }

  _dispose(): void {
    if(isPresent(this.translationLoadedSub)) {
      this.translationLoadedSub.unsubscribe();
      this.translationLoadedSub = undefined;
    }
  }

  ngOnDestroy(): void {
    this._dispose();
  }
}

You can view the live implementation on Plunker here: https://plnkr.co/edit/VMqCvX?p=preview.

Answer №2

Instead of striving for synchronous code, it is advisable to let the TranslationService notify you once it's prepared:

export class TranslationService {
    // ...

    get readyStatus() {
        return !!this._messages;
    }
}

Subsequently, the pipe can deliver translations only when the _messages property is populated.

export class TranslatePipe implements PipeTransform {
    // ...

    transform(value: string, args: string[]) : any {
        return this._translation.readyStatus
            ? this._translation.getTranslationByKey(value) : null;
    }
}

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

ReactJS - Code runs flawlessly on initial execution

Currently, I am diving into the world of ReactJS and JavaScript. I have encountered an issue where my JavaScript code only seems to run once when I initially start the test server or build it. After that, it appears broken. Could this be due to how React ...

Enhanced Slider Display featuring Multiple Posts for Improved Performance

My Sample Page features a slider that displays over 200 posts, each containing 5 images. However, the slider loads all the images at once, causing my page speed to be very slow. I am looking for an optimized way to display the slider without compromising l ...

Retrieve LatLng coordinates for a Heatmap on Google Maps using data stored in a MySQL database

I am currently working on a GIS project where I aim to develop a hotspot crime mapping feature using Google Heatmap from the Google Maps API. I have a large dataset of crime locations (including latitude and longitude) stored in a MySQL database. While exp ...

Update the color of the text depending on the background color

When hovering over my CTA, a sliding effect occurs. However, I am facing an issue with the text being difficult to read depending on the background color. To better understand what I'm trying to achieve, you can view the demo here: Demo on CodePen T ...

Find the MD5 hash of the image uploaded using Java WebDriver

I am trying to calculate the MD5 hash of images that are loaded in Firefox webdriver using Java. import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.JavascriptExecutor; String script = "var ...

Establish HTTP headers for accessing the Oxford API in an Angular 6 application

public performAutocomplete(wordInput):any { let headersOptions = { headers:{ 'Accept': 'application/json', 'app_id': 'myid', "app_key": "mykey" } as any } this.wordTyped = wordInp ...

How to reference an image source using a relative path in jQuery qTip

Hello, I'm working on a jQuery qTip tooltip for my web application and I'm facing an issue with setting a relative path for an image in the tooltip. Here is the code snippet I am using: $('#behind-the-behaviour span[title]').qtip({ ...

Conceal THREE.Mesh using dat.gui controls

I'm exploring the process of creating 3D shapes for 3 buildings, starting with the outlines (with X and Y values for each line start/end) and then extruding them. Despite my search on Google yielding no helpful results, I'm reaching out to you f ...

Tips for adjusting a JavaScript object using attribute names stored in an array

Currently, I am utilizing Node.js and have a jsonFile that allows me to create an object: var dateFile = './Dictionnary/lastUpdate.json'; var dateObj = jsonfile.readFileSync(dateFile); The object looks like this: var dateObj = { "l2D": "2018 ...

Modifying the default value script to function across various rows

Utilizing a script called jquery.defaultvalue.js, I have added default text to various input fields on a form: <script type='text/javascript'> jQuery(function($) { $("#name, #email, #organisation, #position").defaultvalue("Name", "Emai ...

Dynamically updating the scroll area in Ionic using real-time data

Hello, I am currently working on an Ionic project and have created a code pen for it. At the moment, the code pen just displays an image with two buttons for zooming in and out. However, I have encountered an issue. When I click on zoom in and scroll to ...

An Ajax GET request will not be able to locate the JSON file

I am having issues retrieving Key and Values from a JSON file using the function provided. Despite placing the 'datafile.json' in the same directory, the code fails to execute the alert(weblink) function, while the alert('test 1') works ...

Is it necessary to encapsulate the last Typsecript export in a module?

I am facing the challenge of exporting multiple models and services within a TypeScript module. Origin models/User.ts import {IModel} from "./IModel"; export interface User extends IModel { // ... } services/UserService.ts import {inject} from & ...

Eliminate records using Angular combined with PHP

In my quest to delete data from MySQL using PHP and Angular, I have come up with the following code: Angular $scope.delete = function(){ that = this; $http.get("delete.php").success(function(data){ $scope.users.splice(that.$index, 1) ...

Is There a Name Clash Issue with Dependency Injection in AngularJS?

Let's say I have two modules, finance2 and finance3, both of which define a service called currencyConverter. If I specify that my main module only depends on finance2, I can inject the service like this: angular.module('invoice2', [' ...

Differentiating between model types and parameters in Prisma can greatly enhance your understanding of

Consider the following scenario: const modifyData = async(data, settings) => { await data.update(settings) } In this case, the data refers to any data source, and the settings consist of objects like where and options for updating the data. How can ...

Oops! An error occurred while trying to find the _mongodb._tcp.blog-cluster-0hb5z.mongodb.net. Please check your query settings and try again

My free Mongo Atlas cluster suddenly stopped connecting, even though everything was working fine before. Strangely, I can see that data has been collected on the MongoDB website. It's puzzling why this issue occurred and now my entire site won't ...

Decoding JSON - JavaScript - null value

My JSON data is as follows: [ { "0": "324", "1": "Cavill ", "2": "11", "3": "100018463", "4": "RAR", "5": "DummyX", "6": "DummyY", "7": "Moretext", "8": "moretext", "id": "lol", "teacher": "Specsavers ", " ...

Tips for organizing classes in a Node module

Is it recommended to organize classes in a node module using the following method, or is there a more efficient way to achieve this? // mymodule/core.js module.exports = { ClassA: require('./class/ClassA'), ClassB: require('./class ...

Could a website potentially generate enough heat to speed up the draining of a Android device's battery?

As I work on a Single Page Application using AngularJS for my website, my client has expressed concerns about users' devices heating up and experiencing faster battery drain when accessing the site. The technologies employed in development include PH ...