jacques
jacques

Reputation: 1

Reactive non-mongo variable in angular-meteor

I couldn't find an answer or a solution to a challenge yet: How can I bind a variable (Session variable, no mongo collection) reactively in angular-meteor?

I'm converting from standalone meteor. Here I could use the template.helper method. As I can't use templates (and iron:router) anymore with angular-meteor and angularui-router, I can't bind reactivity to the helper anymore (at least in my understanding).

I tried this in an meteor-angular controller, which belongs to a sentence.tpl file:

$scope.parsestring = function(input_string){
            tokenizer(input_string);
        };

$scope.sentence_type = Session.getJSON("current_sentence.sentence_type");

Tokenizing works (I can see it in the debugger), but the value is only displayed, when I reload the page. What I want to achieve is tokenizing a string from an input field into a JSON representation (the tokenizer takes care of that) and displaying it similtaniously from the JSON representation in a structured way (separate html input elements, which are created dynamically). sentence_type is the variable that should be used on the html-page to show and change the sentence type, which can change while typing.

Anybody has some hints? Maybe, I could also use some Angular feature that I don't know?

Cheers, Jan

Code repo:

My current code looks like this:

My code looks similar to this:
angular.module('ngaignt').controller("InteractorCtrl", ['$scope', '$meteor', '$meteorCollection',
      function ($scope, $meteor, $meteorCollection) {
        // Autorun is necessary to make reactive variables out of the JSON returns
          var c = Tracker.autorun(function (comp) {
            $scope.verb_type = Session.getJSON("current_verb.type");
            $scope.object_type = Session.getJSON("current_object.type");
            $scope.verb_attributes = _.toArray(Session.getJSON("current_verb.attributes"));
            $scope.object_attributes = _.toArray(Session.getJSON("current_object.attributes"));

            if (!comp.firstRun) {
                // only do not do aply at first run becaulse then apply is already running.
                $scope.$apply();
            }
        });

        $scope.parsestring = function (input_string) {
            interactor(input_string);
        };
        //$scope.on('$destroy', function () {c.stop()});
     }]);

Upvotes: 0

Views: 854

Answers (3)

Urigo
Urigo

Reputation: 3185

good question and the best answer depend on your needs.

There are 2 possible solutions:

  1. If you want to bind a Session variable to a scope variable, use the $meteorSession service. What it does is that every time the scope variable will change, it will change to Session variable (and trigger an autorun if it's placed inside one). and every time the Session variable will change, the scope variable will change as well (and change the view that it's placed upon).

  2. If you are using the Session variable just to get a variable reactive (meaning trigger an autorun), you should use getReactively . this just returns the already existing scope variable but trigger an autorun every time it changes. a good example of this can be found it our tutorial.

    • Note: In anyway, when you use Tracker.autorun inside Angular, you need to connect it to a scope. this can be easily done if you replace Tracker.autorun with the $meteorUtils autorun function

Would be great if you could share a repo so that I can look on the broader perspective and could better determine what's the best solution from the two.

Upvotes: 1

jacques
jacques

Reputation: 1

Based on another answer about "session" reacitivity, I could solve the problem. Just use the approach described in the link https://stackoverflow.com/a/21046935/4035797. You have to substitute Deps.autorun by Tracker.autorun though as Deps is deprecated and you have to make the scope variables for use in the template reactive (e.g., $scope.sentence_type = Session.getJSON("current_sentence.sentence_type");) and not the tokenizer.

Upvotes: 0

Kyll
Kyll

Reputation: 7139

To use reactive variables, you need a reactive computation. You may need to use Tracker.autorun:

$scope.parsestring = Tracker.autorun(function(someStringInSession){
        tokenizer(Session.get(someStringInSession));
});

Or you can use Tracker.autorun(func) wherever you use a reactive variable to reactively rerun a function when the variable changes.

Upvotes: 1

Related Questions