Use the syntax ""'controller' as"" instead of $scope

I found a helpful AngularJS+ASP.NET tutorial that introduces the concept of $scope, but I am interested in using the newer syntax controller instead. I came across a useful discussion on this topic in a question titled: "AngularJs "controller as" syntax - clarification?"

However, my attempt to implement this change is currently not functioning as expected. The issue lies in the page's invocation of $http.get within the nextQuestion() function, yet the view remains static with only the title displaying as "loading question...".


Below is the code snippet:

JS http://pastebin.com/RfngRuZD

var app = angular.module('QuizApp', [])

app.controller('QuizCtrl', ['$http', function ($http) {
    this.answered = false;
    this.title = "loading question...";
    this.options = [];
    this.correctAnswer = false;
    this.working = false;

    this.answer = function () {
        return this.correctAnswer ? 'correct' : 'incorrect';
    };

    // GET
    this.nextQuestion = function () {
        this.working = true;
        this.answered = false;
        this.title = "loading question...";
        this.options = [];

        $http.get('/api/trivia').success(function (data, status, headers, config) {
            this.options = data.options;
            this.title = data.title;
            this.answered = false;
            this.working = false;
        }).error(function (data, status, headers, config) {
            this.title = "Oops... something went wrong.";
            this.working = false;
        });
    };

    // POST
    this.sendAnswer = function (option) {
        this.working = true;
        this.answered = true;

        $http.post('/api/trivia', { 'questionId': option.questionId, 'optionId': option.id }).success(function (data, status, headers, config) {
            this.correctAnswer = (data === "true");
            this.working = false;
        }).error(function (data, status, headers, config) {
            this.title = "Oops... something went wrong.";
            this.working = false;
        });
    };
}]);

Index.cshtml http://pastebin.com/YmV1hwcU

@{
    ViewBag.Title = "Play";
}

<div id="bodyContainer" ng-app="QuizApp">
    <section id="content">
        <div class="container">
            <div class="row">
                <div class="flip-container text-center col-md-12" ng-controller="QuizCtrl as quiz" ng-init="quiz.nextQuestion()">
                    <div class="back" ng-class="{flip: quiz.answered, correct: quiz.correctAnswer, incorrect: !quiz.correctAnswer}">
                    
                    <p class="lead">{{quiz.answer()}}</p>
                    <p>
                        <button class="btn btn-info btn-lg next option" ng-click="quiz.nextQuestion()" ng-disabled="quiz.working">Next Question</button>
                    </p>
                </div>
                    <div class="front" ng-class="{flip: quiz.answered}">
                        <p class="lead">{{quiz.title}}</p>
                        <div class="row text-center">
                            <button class="btn btn-info btn-lg option"
                                ng-repeat="option in quiz.options" ng-click="quiz.sendAnswer(option)" ng-disabled="quiz.working">
                                {{option.title}}
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>
</div>

@section scripts{
    @Scripts.Render("~/Scripts/angular.js")
    @Scripts.Render("~/Scripts/app/quiz-controller.js")
}

Answer №1

The reason why using this in controllers is not ideal has been uncovered. The context of the this inside your $http success promise does not match that of the controller, as it operates within a separate environment. This issue could be avoided by accessing $scope through closure.

To address this, one can create a variable like var that = this; and then utilize that instead.

Answer №2

Another approach is to utilize the bind function in JavaScript and specify the desired context for the 'this' keyword.

$http.get('/api/trivia').success(function (data, status, headers, config) {
    this.options = data.options;
    this.title = data.title;
    this.answered = false;
    this.working = false;
}.bind(this));

Answer №3

Just wanted to share that this solution worked perfectly for me, much appreciated!

//form.blade.php

<md-content flex ng-controller="EmployeeController as child" ng-cloak>
 <md-input-container>
    <label>State</label>
    <md-select name="fk_state" ng-model="form.fk_state">
        <md-option><em>Select</em></md-option>
        <md-option ng-repeat="state in child.states" ng-value="state.uf">
            [[state.uf]]
        </md-option>
    </md-select>
 </md-input-container>
</md-content>

//employeeController.js

angular.module("app").controller('EmployeeController',
 function($scope, $q, utilsFactory){

    var that = this;

    //service that contains a $http request
    utilsFactory.getAll('states').then(function(response) {
        that.states = response.data;
        console.log(that.states); //this will be accessible by child.states
    });
 }
)

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

javascript Issue with setInterval function not triggering for an object

Hey there! I'm currently working on creating a JavaScript object and implementing the setInterval method. However, I seem to be running into an issue. When I remove the quotes from the code snippet, the method only runs once. Do you have any insights ...

What is the best way to update a field within a MongoDB document based on a specified duration?

In the process of creating a new application with JS, Node.JS, Express, and MongoDB, I am implementing a feature where users can purchase listings. These listings are stored as documents in a MongoDB database. My goal is to have the listings automaticall ...

I need assistance in testing the component with the react query library as it requires a query client

I am encountering a specific issue while adding tests and need help to resolve it. I want to know how to set the query client inside the register page itself. Register.jsx --- Main page for user registration where I am attempting DOM testing. /* eslint ...

The Relationship Between Project Organization and File Interconnections

Transitioning from GWT to AngularJS has been quite the experience for me as I delve into a new project. In order to make the switch seamless, I've been exploring various project structures and dependency management options that work best with Angular ...

Having trouble troubleshooting this issue where the object data is displaying in the console, but encountering an error when trying to use the resetValue

Index.html I am facing an issue while reading data from an object and the seek bar is giving a null error. The images and songs are stored locally, and I am trying to access them. <div class="music-player"> <div class="song&qu ...

Changing positions of nodes and links in D3 v4 force layout during transition

Utilizing D3 v4 to create a dynamic social network visualization, I have included an example at the following link: https://jsfiddle.net/wand5r6L/1/. In this particular example, there are two years worth of data being displayed. My goal is to update the n ...

Removing users from a Socket.IO chat room using Node.js

I am facing an issue with removing users from Socket.IO when their browser is closed. The 'user' in the array 'users[]' is not getting removed or updated. Additionally, I would like to update the users on the client side as well. Can so ...

Pressing ctrl and clicking on a link created with the tag element in VueJS will activate

When using a router link without an anchor tag, I am able to ctrl+click the link to open it in a new tab. However, when used with a tag (e.g., tag="td"), the ctrl+click functionality no longer works. The same issue occurs with clickable elements generated ...

Converting HTML5 FormData object to raw payload using frontend javascript: A Step-by-Step Guide

Can anyone help me with extracting the entire POST request payload stream in my browser side script? I am facing difficulty when the body is a FormData object, especially containing a file blob. Is there a convenient way to achieve this? The main purpos ...

The User Identifier field is updated when transitioning from a view model to a controller

On the admin page, I have implemented a feature for changing user roles. By passing the userId, I retrieve user information such as their name. Users can have different roles like admins, employees, customers, or companies (with three variations). To manag ...

Targeting lightgallery.js on dynamically added elements in Javascript: The solution to dynamically add elements to

I am facing a challenge in targeting dynamically added elements to make them work with lightgallery.js. Take a look at the example below: <div id="animated-thumbs" class="page-divs-middle"> <!-- STATIC EXAMPLE --> ...

How come Vue.js is not showing the image I uploaded?

Even though I can successfully print the image URL, I'm facing an issue where the img tag is not displaying it, despite my belief that I've bound it correctly. <html> <head> <title>VueJS Split Demo</title> <script t ...

Angular does not support fetching JSON files

update: The code has been modified to include the latest suggestions provided by you all. I've got this data.json file: [{ "codigo": 21420, "desc": "itv orion 20 a", "prod_24_h_kg": 22 }, { "codigo": 21421, "desc": "itv orion 20 w", "prod_24_h_kg": ...

Ajax Complete adds Jquery two times in a row

I have a simple ajax complete call that is designed to add some text after an ajax load finishes. However, I'm encountering an issue where the information is sometimes displayed multiple times. I suspect there might be something missing in my approach ...

Sending data from a bespoke server to components within NextJS

My custom server in NextJS is set up as outlined here for personalized routing. server.js: app.prepare() .then(() => { createServer((req, res) => { const parsedUrl = parse(req.url, true) const { pathname, query } = parsedUrl ...

Using HTML5 video with cue points and stop points

I've noticed that there are various options available for implementing cuepoints in HTML5 videos, such as using PopcornJS or CuepointsJS to trigger play events at specific times within the video track. However, I am wondering if there is a solution t ...

Steps for implementing a delete button in a custom table on yii

I've encountered an issue with a form that uses ajaxSubmitButton to add product items to an HTML table. The ajaxSubmitButton successfully adds items using AJAX to update the table's <tr> and <td> elements. I've also included a de ...

Mastering Programming Languages through Effective Page Design

Currently, I am collaborating on a project that involves a Master Page in VB. However, I am facing a challenge as I am unfamiliar with coding in VB. I have expertise in coding in C#, C++, and similar languages within this syntax branch. I am wondering if ...

In what way do Tumblr and Google+ creatively arrange images like a jigsaw puzzle?

I'm interested in creating a unique gallery of images and I'm curious about how to stack them similar to Google and Tumblr. What I mean is, on an archive page of Tumblr, the images are stacked in columns like this: However, I also want the imag ...

How can I arrange individual events in agendaWeek view on FullCalendar.io and then merge them all into one line?

I am using Fullcalendar.io version 2 When I switch to the agendaWeek mode, all my events are displayed on one line in each day square. As a result, the more events I have, the thinner the event blocks become. Is there a way for me to display only one eve ...