0

I'm fairly new to angular and Im wondering how to achieve the following:

Im using a ternary condition in my variables to switch between two languages without refreshing my page and display items (ng-repeat) with the correct titles.

{{isEnglish ? item.name_en : item.name_fr}}

I have a toggle switching isEnglish to true or false, but the the variables don't update themselves when switching the boolean. Do I need to apply the changes? is there a way to do so?

language toggle

<a href="" class="fb border_link" ng-click="changelanguage();">
    {{displayLanguage}}
</a>

ng-click function

$scope.changelanguage = function(){
    console.log("changing language");
    console.log($scope.$parent.isEnglish);
    if($scope.selectedLanguage === 'en'){
      $translate.use('fr');
      $scope.$parent.isEnglish = false;
      console.log($scope.$parent.isEnglish);
      $scope.selectedLanguage = 'fr';
      $scope.displayLanguage = 'English';
      console.log("en");
    }
    else{
      $translate.use('en');
      $scope.$parent.isEnglish = true;
      console.log($scope.$parent.isEnglish);
      $scope.selectedLanguage = 'en';
      $scope.displayLanguage = 'Français';
      console.log("fr");
    }
  }
3
  • You could post more code.. Commented Jul 11, 2016 at 3:36
  • done, if that help. the ternary condition is inside a ng-repeat div Commented Jul 11, 2016 at 3:43
  • @SKYnine: see my second update. Commented Jul 11, 2016 at 4:13

2 Answers 2

2

Try making isEnglish an object property like settings.isEnglish. Angular has some issues with raw variables attached to scope.

Sign up to request clarification or add additional context in comments.

2 Comments

@SKYnine first of all I'd strongly suggest not to use $parent and simply use a service to use the same data in two different scopes. Also, isEnglish shouldn't be a variable either, it should be a function (or you could even attempt to do the check right in the view if you want) by returning $scope.selectedLanguage === 'en'. Also the raw variable like selectedLanguage and displayLanguage (arguably to use two different variables) could be in an object just like I said in my answer to avoid any trouble. Give this a try and shoot me back.
I made an object out of my settings and it started working. I couldn't use a service cause I need scope variable to be dynamic and not only at first load. Anyway, don't understand why it started working (cause I tried the object shape yesterday)
0

Update 2: Since you're assigning isEnglish to the $scope.$parent you could have a $scope-related problem.

To help troubleshoot I'd use something like Batarang to figure out what the value of $scope.isEnglish is for various $scope's. Alternatively, you could put an {{ isEnglish }} binding next to your ternary to confirm that isEnglish is being set when changelanguage is called. If it isn't it's going to come down to how your child and isolated scopes are being structured.


Update 1: The code you've posted in your question works fine. Here's a working plunkr. Judging from your comment, maybe you have a child scope you're assigning to in your ng-click. Are you doing the assignment directly in the ng-click expression or is it done through a method (like in my plunkr)?

JS

app.controller('MainCtrl', function($scope) {
  $scope.isEnglish = true;

  $scope.toggle = function _toggle() {
    $scope.isEnglish = !$scope.isEnglish;
  };

  $scope.item = {
    name_en: 'en name',
    name_fr: 'fr name'
  };
});

HTML

<body ng-controller="MainCtrl">
  <div>
    <button ng-click="toggle()">
      Toggle isEnglish
    </button>
  </div>
  <br>
  <br>

  <div>
    isEnglish:
  </div>
  <div>
    <b>{{ isEnglish }}</b>
  </div>
  <br>

  <div>
    isEnglish ? item.name_en : item.name_fr:
  </div>
  <div>
    <b>{{isEnglish ? item.name_en : item.name_fr}}</b>
  </div>
</body>

You may need to wrap the toggle in a $scope.apply call if it's something like a custom directive that happens outside the digest cycle:

// 'scope' is argument in directive link function.
function toggle() {
  scope.$apply(function () {
    scope.isEnglish = !scope.isEnglish;
  });
}

4 Comments

$scope.isEnglish is changed within a ng-click function so digest cycle is already in progress. using $apply() within is triggers error. Everything from the function is working as expected, even the isEnglish toggle. it is just the variable in the html that don't update themselves...
It's always recommended wrapping the $scope.$apply in a $timeout call so it doesn't enter in conflict with the ongoing $digest flow.
adding a $timeout indeed prevent the $apply to trigger errors. but the result is the same it doesn't update the variables :(
the change is done in a function. I've added some code to my question to reflect what I have.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.