I am unable to access Angular $scope in the HTML Template, although I can view it in the console log

I have been following some online tutorials and using the angularjs-template to start learning Angular. However, I am facing an issue where the page (html template) is not updating with the controller. It seems like there is a problem in how I've set up the controller because the values are not being displayed in the html template.

I tried implementing recommendations from best practice guides by wrapping my components in an 'Invoked Function Expression' and separating out the controller, service, and service manager. But it looks like I've messed this up somewhere and need assistance in identifying the mistake.

When checking the console, I can see that $scope.metric contains the desired information, indicating that the controller has successfully retrieved data from the API via the metricService. However, I'm unable to display these results on the html page e.g. metric.id.

Any help would be greatly appreciated as I've exhausted all my efforts trying to resolve this issue.

metric.html

<div class="panel panel-primary">
<div class="panel-body">
     <!-- Try First Way to Print Results -->
    Id: <span ng-bind="metric.id"></span></br>
    Name:<input type="text" ng-model="metric.metadata.name" /></br>

    <!-- Try Second Way to Print Results -->
    <p data-ng-repeat="thing in ::MEC.metric track by $index">
        {{$index + 1}}. <span>{{thing.metadata.name}}</span>
            <span class="glyphicon glyphicon-info-sign"></span>
        </a>
    </p>

<!-- Try Third Way to Print Results -->
    Id: <span ng-bind="Metric.metricId"></span></br>
    Id: <span ng-bind="Metric.id"></span></br>
    Id: <span ng-bind="metricService.id"></span></br>

<!-- Try Fourth Way to Print Results -->
      Id: <strong>{{::MEC.metric.id}}</strong></br>
      Name: <strong>{{::MEC.metric.metadata.name}}</strong></br>
      Height: <strong>{{::MEC.metric.type}}</strong>
</div>

metricController.js

(function () {
    'use strict';

    angular.module('app.metric', ['app.metricService', 'app.metricManager'])    
        .controller('MetricController', MetricController) 

        MetricController.$inject = ['$scope', 'metricManager', '$log'];

        function MetricController($scope, metricManager, $log) {

            metricManager.getMetric(0).then(function(metric) {
                $scope.metric = metric
                $log.info('$scope.metric printed to console below:');
                $log.info($scope.metric);
            })
        }
})();

metricService.js

(function () {
    'use strict';

    angular.module('app.metricService', [])    

    .factory('Metric', ['$http', '$log', function($http, $log) {  
        function Metric(metricData) {
            if (metricData) {
                this.setData(metricData);
            }
            // Some other initializations related to book
        };

        Metric.prototype = {
            setData: function(metricData) {
                angular.extend(this, metricData);
            },

            delete: function() {
                $http.delete('https://n4nite-api-n4nite.c9users.io/v1/imm/metrics/' + metricId);
            },

            update: function() {
                $http.put('https://n4nite-api-n4nite.c9users.io/v1/imm/metrics/' + metricId, this);
            },

            hasMetadata: function() {
                if (!this.metric.metadata || this.metric.metadata.length === 0) {
                    return false;
                }
                return this.metric.metadata.some(function(metadata) {
                    return true
                });
            }
        };
        return Metric;
    }]);

})();

metricManager.js

(function () {
    'use strict';

    angular.module('app.metricManager', [])   

    .factory('metricManager', ['$http', '$q', 'Metric', function($http, $q, Metric) {  
    var metricManager = {
        _pool: {},
        _retrieveInstance: function(metricId, metricData) {
            var instance = this._pool[metricId];

            if (instance) {
                instance.setData(metricData);
            } else {
                instance = new Metric(metricData);
                this._pool[metricId] = instance;
            }

            return instance;
        },
        _search: function(metricId) {
            return this._pool[metricId];
        },
        _load: function(metricId, deferred) {
            var scope = this;

            $http.get('https://n4nite-api-n4nite.c9users.io/v1/imm/metrics/' + metricId).then(successCallback, errorCallback)

                function successCallback(metricData){
                    //success code
                    var metric = scope._retrieveInstance(metricData.id, metricData);
                    deferred.resolve(metric);
                };

                function errorCallback(error){
                    //error code
                    deferred.reject();
                }
        },

        /* Public Methods */
        /* Use this function in order to get a metric instance by it's id */
        getMetric: function(metricId) {
            var deferred = $q.defer();
            var metric = this._search(metricId);
            if (metric) {
                deferred.resolve(metric);
            } else {
                this._load(metricId, deferred);
            }
            return deferred.promise;
        },

        /* Use this function in order to get instances of all the metrics */
        loadAllMetrics: function() {
            var deferred = $q.defer();
            var scope = this;
            $http.get('ourserver/books')
                .success(function(metricsArray) {
                    var metrics = [];
                    metricsArray.forEach(function(metricData) {
                        var metric = scope._retrieveInstance(metricData.id, metricData);
                        metrics.push(metric);
                    });

                    deferred.resolve(metrics);
                })
                .error(function() {
                    deferred.reject();
                });
            return deferred.promise;
        },

        /*  This function is useful when we got somehow the metric data and we wish to store it or update the pool and get a metric instance in return */
        setMetric: function(metricData) {
            var scope = this;
            var metric = this._search(metricData.id);
            if (metric) {
                metric.setData(metricData);
            } else {
                metric = scope._retrieveInstance(metricData);
            }
            return metric;
        },

    };
    return metricManager;
}]);
})();

Snippet from App.routes

 .state('root.metric', {
                    url: 'metric',
                    data: {
                        title: 'Metric',
                        breadcrumb: 'Metric'
                    },
                    views: {
                        'content@': {
                            templateUrl: 'core/features/metric/metric.html',
                            controller: 'MetricController',
                            controllerAs: 'MEC'
                        }
                    }
                })

Console https://github.com/pamigomp/angularjs-template

Answer №1

When setting up a controller alias with `$scope`, it is important to understand the difference between the two concepts. In this example, the controller alias is created as MEC using the `controllerAs` syntax. If you utilize controller alias, your code should look like this:

function MetricController($scope, metricManager, $log) {
    var MEC = this;
    metricManager.getMetric(0).then(function(metric) {
        MEC.metric = metric
        $log.info('$scope.metric printed to console below:');
        $log.info($scope.metric);
    })
}

If you prefer not to use a controller alias and instead share data between the view and controller via `$scope`, you can use a syntax like {{::metric.metadata.name}} in your view while keeping the controller function unchanged.

Furthermore, when choosing an alias name like MEC or abc, it is best practice to adhere to the convention of using `var vm = this` and `controllerAs: 'vm'`. If you define the controllerAs as 'xyz', then in your view, you should access the model using `xyz`.

Answer №2

There seems to be an issue with the HTML in your view. Make sure you are using Angular expressions correctly when binding data. If you want to use the alias name ::MEC, you need to specify your controller with the as keyword, like this: ng-controller="xyz as MEC". You can also refer to a working example on Plunker.

<div class="panel panel-primary">
    <div class="panel-body">
        <!-- Try First Way to Print Results -->
        Id: <span ng-bind="metric.id"></span>
        <br> Name:
        <input type="text" ng-model="metric.metadata.name" />
        <br><br><br><br>

        <!-- Try Second Way to Print Results -->
        <p data-ng-repeat="thing in [metric] track by $index">
            {{$index + 1}}. <span>{{thing.metadata.name}}</span>
            <span class="glyphicon glyphicon-info-sign"></span>
        </p><br><br><br>

        <!-- Try Third Way to Print Results -->
        Id: <span ng-bind="metric.metricId"></span>
        <br> Id: <span ng-bind="metric.id"></span>
        <br><br><br>

        <!-- Try Fourth Way to Print Results -->
        Id: <strong>{{::metric.id}}</strong>
        <br> Name: <strong>{{::metric.metadata.name}}</strong>
        <br> Height: <strong>{{::metric.type}}</strong>
    </div>
</div>

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

Transmit data via AJAX to the RequestBody

Although seemingly simple, this issue has proven to be quite challenging. I am confident that it can be easily resolved, but the solution continues to elude me. Thank you for any assistance you can provide. Here is the code snippet in question : var samp ...

What is the best approach to accumulate model data in an Angular JS service or controller through a series of consecutive calls?

I am facing a challenge where I need to display the results of multiple REST server calls on a single page using AngularJS. The initial call retrieves details about a specific product, including the IDs of other related products. My goal is to not only s ...

Enhance npm package by implementing custom functionality with React Component

I have designed an app that bears a striking resemblance to the following code: class MyCustomApp extends React.Component { constructor (props) { super(props) this.state = { tags: [ { id: 1, name: "Oranges" }, { id: 2, ...

When a large object changes value in Firebase, does it transfer only the delta change in internet bandwidth?

Hello, I am working with a node that contains an array of 1000 nodes, totaling around 60KB in size. rootRef.on('value', function (snapshot){ //callback every changes props , full list obj }); I would like to know: - When a node in ...

In Flow, how is the asterisk (*) type utilized and what is its counterpart in TypeScript?

My expertise lies mostly in TypeScript, but I recently came across Flow which seems quite similar to TS in many aspects. However, one thing that caught my attention is the asterisk (*) type in Flow. Initially, I thought it was just another way of represent ...

Generate an interactive pie chart with visually appealing animations using jQuery, without any actual data

My task involves creating a pie chart to visually display different categories. However, the challenge is that the chart does not contain any data, ruling out options like Google charts or other data-driven chart makers. As a solution, I have turned the pi ...

Experimenting with animating an element through onClick event using JavaScript

I would like to create an animated div using JavaScript that activates on click. <div class="Designs"> <p>Designs</p> <div class="Thumbnails" data-animation="animated pulse"> <a href=" ...

What is the best way to retrieve the content of HTML tags from a string using JavaScript or AngularJS?

I have a string with mixed content of HTML tags and text. Here is an example: var str = "<p></p><p><i>blabla</i></p><p><i><b>blaaaaaablaaaaa</b></i></p><iframe src="..." height=" ...

Initiating an audio call exclusively via SimpleWebRTC

I'm currently utilizing a jQuery plugin for WebRTC found here. My goal is to initiate an audio call only, but I am struggling to find a function within the plugin that allows for this. The code snippet I am using with autoRequestMedia set to false is ...

Tips for fixing the async/await problem in JavaScript

Here is the code I've been working on: let icsFileData = []; icsFileData = filterAttachmentArray.map(async(file) => { let buff = new Buffer(file.data, 'base64'); let text = buff.toString('ascii'); const data = await ical ...

Retrieving PHP data, utilizing the split method to break apart the commas within the string, and then displaying the information within a div using AJAX for a continuous refresh cycle every 3 seconds

I am attempting to extract data from a PHP string like '10,58,72,15,4,723,' and split it by commas into arrays using the split() method. My goal is to then place these arrays into different div elements and update the data every 3 seconds. Below ...

What methods can be used to modify the behavior of tiptap when pasting plain text?

Currently, my goal is to create a visual editor by utilizing the tiptap library. Although v2 of tiptap is more commonly used, there are instances where v1 is necessary. However, I encountered an issue with tiptap's behavior when pasting plain text, ...

The functionality of save() is not compatible with mongoose.Schema

const Information = require('./Models/Information'); ... let sampleData = new Information( dataSample ); sampleData.save( function ( error ){ console.log('testing); if ( error ) { console.log('Error occurred while saving Informa ...

Ways to implement functional component in ReactJs

I am currently working with Reactjs and utilizing the Nextjs framework. In my project, I am attempting to retrieve data from a database using Nextjs. However, I am encountering an error that states "TypeError: Cannot read property 'id' of undefin ...

Calculating values within the TR using jQuery: A step-by-step guide

I have a situation where I am looking to use jQuery to calculate values within a table row. Below is a screenshot of the page where I need to determine the number of working days for an employee and display the count as NWD (Number of Working Days). http ...

Having trouble with Nodejs Express failing to load script files?

I am attempting to launch an Angular application through node-express. 1 File Structure AngularNode public /core.js /index.html project.json server.js 2 server.js var express = require('express'); var app = expres ...

BroccoliMergeTrees function encountered an unexpected data type while attempting to merge trees: TreeMerger (lint) was expecting a Broccoli node, but received an [object

Since switching to Ubuntu 18.04, I've been trying to set up my Ember development environment but have encountered an issue. While my ember project works fine on Windows, I'm getting the error "BroccoliMergeTrees (TreeMerger (lint)): Expected Broc ...

Having trouble with Silverlight running JavaScript?

When I try to call a JavaScript function from a SL component using the HtmlPage.Window.Invoke api, it works fine if the function is defined in the page (html). For example: HtmlPage.Window.Invoke("publishValue", topic, jsonObject); However, if I place th ...

typescript error is not defined

While browsing online, I came across a post discussing how to transfer data from an MVC model to a .ts file. The suggestion was to include the following code: <script type="text/javascript"> var testUrl = @Html.Raw(Json.Encode(Model.testUrl) ...

Unable to iterate through nested arrays in Contentful mapping

I am facing an issue while trying to map further into the array after successfully retrieving data from Contentful. The error message field.fields.map is not a function keeps popping up and I can't figure out what I'm doing wrong. export defau ...