AngularJS factory or filter failing to update properly

I have been working on a system that manages translations in my factory. I set the language as a string and then use a filter to update the view when the language changes.

Everything works fine if I define the language in the view beforehand, but when I try to change the language using a button click, nothing happens.

Can someone please help me figure out what I might be doing wrong?

This is a snippet of my view:

<div ng-app="testApp">
  <div ng-controller="myController">
    <p >{{ data.title | translate }}</p>
    <p >{{ data.text }}</p>
    <button type="button" ng-click="changeLanguage('en')">English</button>
    <button type="button" ng-click="changeLanguage('sl')">Slovene</button>
  </div>
</div>

This is part of my script:

angular.module('langService', [])
  .factory('Language', function() {
  var currentLanguage = 'en';

  return {
    setCurrentLanguage: function(value) {
      currentLanguage = value;
    },
    getCurrentLanguage: function() {
      return currentLanguage;
    }
  }
});

var testApp = angular.module('testApp', ['langService']);

testApp.controller('myController', function ($scope, Language) {
  $scope.data = {
    title: 'PAGE_TITLE',
    text :'some random page text'
  };

  $scope.changeLanguage = function(value) {
    Language.setCurrentLanguage(value);
  }
});

testApp.constant('Translations', {
  en: {
    'PAGE_TITLE': 'Hi!'
  },
  sl: {
    'PAGE_TITLE': 'Živjo!'
  }
});

testApp.filter('translate', function(Translations, Language) {
  return function(input) {
    return Translations[Language.getCurrentLanguage()][input] || '';
  };
});

I've put together an example on codepen to test it out before incorporating it into a project.

Any assistance would be greatly appreciated.

Answer №1

A stateful filter is generally not recommended, but there are valid use cases like yours that require periodic re-evaluation on the digest loop. In order to indicate that your filter is stateful, it needs to be appropriately "marked."

testApp.filter('translate', function(Translations, Language) {

  function translateFilter(input) {
    return Translations[Language.getCurrentLanguage()][input] || '';
  };

  // Marking as stateful
  translateFilter.$stateful = true;

  return translateFilter;

});

For more information on "stateful" filters, refer to the docs: https://docs.angularjs.org/guide/filter

By the way, for translations, consider using angular-translate. You can explore their filter implementation here: https://github.com/angular-translate/angular-translate/blob/master/src/filter/translate.js

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

Changing the entire content of a webpage from the server using AJAX

I am looking to update the entire page content with the click of a button, transitioning from Words.html to SelectNumber.html This snippet is from Words.html <html> <head> <meta charset="UTF-8"> <title>Number Game< ...

Customize mock API requests in Protractor

I have incorporated a mock module into my Angular app for each API call so that I can run it locally. Currently, I am attempting to write a Protractor test case where I need to override one specific API from those mocked APIs. This particular API will dict ...

Is it possible to create Interactive Tabs using a Global BehaviorSubject?

Trying to adjust tab visibility based on different sections of the Ionic app, an approach involving a global boolean BehaviorSubject is being utilized. The encapsulated code has been condensed for brevity. In the provider/service globals.ts file, the foll ...

How can we ensure that the Material-UI <Select> component is as wide as the widest <MenuItem>?

I am attempting to adjust a Mui Select field so that it is the same width as its largest MenuItem. Despite trying to utilize the autoWidth prop on the Select component, I have not been able to achieve the desired result. To better illustrate the issue, I h ...

Reorganize and Consolidate JSON Data

Among the myriad posts discussing JSON formatting, I have yet to find one that caters to my peculiar scenario. Here is the data source in question: data = [{ "LoanOfficer": "Brett", "Year": 2014, "Month": 10, "FundedVolume": 304032.0000, "FundedUnits": 2. ...

Choosing values from a variety of select option boxes using jQuery

I'm experiencing an issue with selecting values in a multiple select option box. Despite my efforts, I haven't been able to get all the desired items selected at once. Currently, when I run the code below, only the first option is being selected ...

Interrupting one process and initiating a new one

Trying to create a simple animation using Velocity.js. This animation will transition between two looping states upon clicking an svg. The first state involves horizontal scaling from scaleX(1) to scaleX(2.5) and back to scaleX(1), while maintaining scaleY ...

Having trouble implementing font css file in Reactjs

When working with Reactjs (Nextjs), every time I try to incorporate "css" into my project, I encounter the following error on my screen: Module not found: Can't resolve '../fonts/fontawesome-webfont.eot?v=4.7.0' How can I solve this issue? ...

Using JavaScript to set a form via a parameter in the URL

Is there a way to dynamically change the SetForm based on a parameter in the URL, such as radio.php?land=form2? I tried doing it this way but it doesn't seem to work. However, when I do it manually via the menu, it works. This is my first time attemp ...

Creating a two-dimensional canvas within a div element using the console

I have some code that currently generates an image in the console when I hit F12. However, I would like to display this image inside a more user-friendly area such as a div on the webpage. I attempted to create a <div class = "mylog"> to place the i ...

Show the current phone number with the default flag instead of choosing the appropriate one using the initial country flag in intl-tel-input

Utilizing intl-tel-input to store a user's full international number in the database has been successful. However, when attempting to display the phone number, it correctly removes the country code but does not select the appropriate country flag; ins ...

What is the process for incorporating dynamic templates in AngularJS?

I have created 3 unique templates (DetailView, CardView, Column) for displaying content on a single page. Users can easily switch between these views. My goal is to display only one view at a time on the page. When the user switches views, I want to remov ...

Implement a menu that can be scrolled through, but disable the ability to scroll on the body of the website

When viewed on a small screen, my website transforms its menu into a hamburger button. Clicking the button toggles a sidebar displaying a stacked version of the menu on top of the normal website (position: fixed; z-index: 5;). This sidebar also triggers a ...

Angular Resolution Verification

I'm currently working on making HTTP calls in Angular and I want to trigger a different service function if an error occurs. The problem is, no matter what the original service call function returns, the promise always ends up being "undefined". Here& ...

Stellar for occasions that don't come around often

Is it worth utilizing a Comet for events that do not require real-time updates, but can have a delay of around 1 minute? Examples could include: updates on Twitter statuses notifications on Facebook While Comet is commonly used in chat applications (suc ...

Revise for embedded frame contents

Is it possible to modify the HTML content of an iframe within a webpage? I currently have this code snippet: <iframe src="sample.html"></iframe> I am looking for a way to edit the contents of sample.html without directly altering the HTML co ...

Tips for monitoring input content "live"

Currently, I am in the process of developing a web form that includes a text field intended to receive numeric values. If the user enters non-numeric characters into this field, the form will not submit. However, there is no error message displayed to noti ...

Get the PDF in a mobile app using HTML5 and Javascript

For my HTML5/JavaScript-based mobile application, I am in need of implementing a feature that enables users to download a PDF file. The PDF file will be provided to me as a Base64 encoded byte stream. How can I allow users to initiate the download proces ...

Troubleshooting app.use in Next.js and express.js: Understanding the issue

Currently, I am working on a project using next.js along with a custom server (express.js). In my API endpoints, I want to utilize some middlewares (such as const attachUser), but strangely I am facing issues when trying to use app.use. The code seems to ...

Is it possible to execute a function defined within an eval() function using setInterval()?

const evaluation = eval(document.getElementById("codearea").value); setInterval(evaluation, 10); I am seeking a way to access a function that is declared within the eval function, for example: setInterval(evaluation.examplefunc, 10) I attempted ...