Passing the AngularJS ng-model from a template to a directive's controller

I have created a directive with a controller that is responsible for building a form to post comments to an API through CommentsService

Here is a snippet of how my directive looks:

app.directive('appComments', function( CommentService ) {
    return {
        restrict: 'E',
        scope: {
            event: '='
        },
        controller: function( $rootScope, $scope, $element ) {

            $scope.comments = [];
            $scope.comment_text = '';

            // load comments if event ID has changed
            $scope.$watch( 'event', function() {
                if( typeof $scope.event != 'undefined' ) {
                    CommentService.get( $scope.event ).then(
                        function( comments ) {
                            $scope.comments = comments;
                        }
                    );
                }
            });

            // post comment to service
            $scope.postComment = function() {
                if( $scope.comment_text != '' ) {

                    CommentService.post(
                        $scope.event,
                        $scope.comment_text,
                        function() {
                            // code to reload comments
                        }
                    );
                }
            };
        },
        templateUrl: '/partials/comments.html'
    };
});

This is the content of my comments.html file used by the directive

<div class="event-comments">
    <p ng-if="!comments.length">
        <span>This event has no comments.</span>
    </p>
    <div 
        class="event-comment" 
        ng-repeat="comment in comments"
    >
        <div class="comment-text">{{comment.text}}</div>
    </div>
</div>
<div class="insert-comment-container" ng-if="!loading">
    <form ng-submit="postComment()">
        <textarea 
            ng-model="comment_text"
        ></textarea>
        <div
            ng-tap="postComment()"
        >Post</div>
    </div>
</div>

This is how I've included it in my main view:

<app-comments event="event.id"></app-comments>

The comments are loading correctly and the event ID is being passed successfully. However, when I try to post a comment, the `comment_text` field appears blank.

I suspect there may be some confusion with scopes or bindings within my directive implementation as I'm still learning about directives.

** update **

I just realized that if I set

$scope.comment_text = 'Initial text'

inside the directive, it displays "Initial text" in the textarea upon rendering the template. When I change the text in the textarea and click the post button, the value of `$scope.comment_text` remains "Initial text". It seems like there is a one-way binding issue at play.

Answer №1

When utilizing a form, it is important to consider the scope it creates. According to the documentation:

If the name attribute is specified, the form controller is made available within the current scope under this specific name.

To ensure proper functionality, assign a name to your form. Alternatively, pass the property as an object property like so:

 <textarea 
            ng-model="comment.comment_text">
 </textarea>

Answer №2

After making the adjustment from comment_text to comment.text, the issue was successfully resolved, following the suggestion provided in this particular response on Stack Overflow:

angular-bootstrap (tabs): data binding works only one-way

By utilizing an object rather than a primitive, it simply utilizes the same reference to the object property instead of duplicating the primitive into the new scope.

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

Unable to show certain special characters when using ng-repeat

I am attempting to showcase an array of objects using ng-repeat. Below is the collection of objects $scope.test = [ { value1: "app\test\maintenance1", value2: "other value1" }, { value1: "app\test\m ...

The progress event of the XMLHttpRequest updates quickly, outpacing the speed of the upload itself

I've been working on setting up an upload form and using xhr to return the upload status to the user. Everything seems to be in place, but I'm facing a strange issue where the callbacks are happening too quickly and showing a higher percentage th ...

Is it possible to use abbreviations instead of full names for object properties in a JSON string?

I'm looking for a way to efficiently convert large and repetitive javascript objects into JSON strings. With the abundance of repeating property names in these objects, I want to streamline the process by replacing those names with predefined abbrevia ...

How can I set a default value for a v-select using a function in vue.js / vuetify?

I'm new to utilizing vuetify and I am curious if there is a method to set a value for a v-select using a function. My form can create an enterprise, leveraging apollo.js to connect with the database. Although all fields populate correctly when modifyi ...

What is the method for providing external parameters to a JOI extension?

Perhaps JOI may not be the ideal tool for this particular task, but I am interested in utilizing it if feasible. Essentially, I have a scenario where a user is sending a request to an API to store specific metric data. Certain metrics are restricted based ...

The second asynchronous function relies on the completion of the first

Despite dedicating two days to exploring async/await and promises, I am still unable to make it work correctly. The challenge lies in the fact that the second await for b relies on the result of the first a. It seems no matter what approach I take, b keep ...

Unreachable prevState when utilizing the useState hook

I am currently working on a component where I need to capture the previousState of an element. However, no matter what I try, it keeps returning the initial value. This suggests that there is some re-rendering happening, causing it to constantly default to ...

Display the image in a pop-up window before executing a jQuery script

Lately, I've been focusing on implementing zoom in and zoom out functionality for images. The plugin I've chosen to use is guillotine. It works flawlessly except for one small hiccup. My goal is to integrate it into a website built with angularJ ...

Is it possible to add to the existing class based on a certain condition?

I have a coding challenge that I need help with. I have a set of code where I want to replace the old value in a class named "content" based on certain conditions. If the value within the class matches one of the values in an Array, then I need to append s ...

The process of dynamically inserting input types into a <td> element using the innerHTML tag is not functioning properly in Internet Explorer

I am facing an issue with dynamically placing input types within a <td> tag - the innerHTML() method is not functioning properly in Internet Explorer, although it works fine in Mozilla. This is how I am inserting the input types using JavaScript, wi ...

There are no warnings or errors when running Yeoman grunt build, however, the dist folder that is generated is not functioning

When working on an Angular application, I typically run either grunt build or grunt serve:dist to generate my production files and deploy them to a remote server. Despite everything appearing fine with no warning messages in the Yeoman logs and yo doctor g ...

Unable to add new tags in Vue multiselect component

Currently, I am utilizing a Vue Multiselect instance with two functions. One function interacts with the database to provide autocomplete functionality, which is working successfully. The second function allows for adding new tags that are not present in t ...

What is the process for dynamically populating a select dropdown based on the selection made in another select dropdown?

I need to dynamically populate the second select box based on the option selected in the first select box. Here's what I have tried so far, but it doesn't seem to be working as expected. HTML: <form id="step1"> <p> Creat ...

Using jQuery to specifically target elements of a specific class that are nested within another element

I am currently using a jQuery function that toggles a drop-down navigation menu by changing its class when clicked: $(function () { $('.nav-titles').on('click', function() { $('.nav-dropdown').toggleClass(& ...

The publish-subscribe feature appears to be ineffective

Recently starting with meteor, I learned about the importance of removing autopublish. So, I decided to publish and subscribe to a collection in order to retrieve two different sets of values. Here is the code on my meteor side: Meteor.publish('chann ...

Google Chrome successfully transmits two variables with AJAX, whereas Mozilla Firefox does not send them

Having an issue with sending two values through ajax - currently only one value is being sent in Mozilla browser. Ajax script: $('#post_submit').click(function() { event.preventDefault(); var great_id = $("#post_container_supreme:first").attr(" ...

svg icon hover effect not displaying color properly

Seeking expertise in incorporating social media icons with a hover effect to turn purple. Encountering an issue where the entire circle of the icon is mistakenly being painted on hover. Refer to the screenshot of the current outcome and desired result. Wo ...

Retrieving data from an external API using Express.js and displaying it on a website

I'm facing a challenge in handling a solution with node.js and express.js utilizing pug for rendering HTML. I need to render on a single page by retrieving values from separate HTTP GET requests from different websites. My goal is for express/node to ...

Error in Node Express server: Status code 0 is not valid

As a beginner node.js/js programmer, I am encountering an error code while trying to make a POST request on my application. The error message reads as follows: Error: [20:22:28] [nodemon] starting `node app.js` Running server on 3000 Mon, 27 Jun 2016 19:2 ...

Personalize the drop area in Filepond

Is there a way to customize the filepond droparea by adding custom HTML with placeholder images to guide users on what kind of images should be uploaded and allow multiple uploads? I attempted to add placeholders in an absolutely positioned container, but ...