Error: Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>

JavascriptDjangoDjango Templatesvue.js

Javascript Problem Overview


I am using Vuejs and I keep getting this warning in the console. Also no data is loaded because of this warning. I checked the code for unwanted tags but did not find any.

Is this because of the javascript code or I have something wrong in my html?

Here is my code:

> HTML

<div class="row">
    <div class="col-sm-12" style="margin-top: 20px;">
        <form class="form-inline" method="GET" action=".">
            <div class="col-sm-3" style="float: right;"><h4>Date:</h4>
                <input class="form-control" style="padding-bottom:0px;" type="text" id="datepicker" readonly="true" name="date" value="2016-06-30">
                <input type="submit" class="btn btn-primary btn-sm" value="Submit" >
            </div>
            
        </form>
        <div class="col-sm-2" style="float: right; margin-top:40px;">
            <button class="btn btn-info" type="button" id="csv_export">Click to Export</button>
        </div>
    </div>
    <div class="col-sm-12" style="margin:20px;">
        <table class="table table-sm table-striped table-bordered" id="absent-list">
            <thead>
                <tr>
                    <th>#</th>
                    <th style="text-align: center; font-size: 15px;">Full Name</th>
                    <th style="text-align: center; font-size: 15px;">Section</th>
                    <th style="text-align: center; font-size: 15px;">Person Called</th>
                    <th style="text-align: center; font-size: 15px;">Person Relation</th>
                    <th style="text-align: center; font-size: 15px;">Phone Number</th>
                    <th style="text-align: center; font-size: 15px;">Absent Reason</th>
                    <th style="text-align: center; font-size: 15px;">Remarks</th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <tr v-show="loading" class="text-center">
                    <td colspan="7">
                        <i class="fa fa-spinner fa-spin fa-4x"></i>
                    </td>
                </tr>
                <tr v-for="record in absent_followback_records">
                    
                    <td style="text-align: center; font-size: 15px;" scope="row"> {{$index + 1}}</td>
                    <td  style="text-align: center; font-size: 15px;">{{record.student_name}}</td>
                    <td  style="text-align: center; font-size: 15px;">{{record.student_section}}</td>
                    <td  style="text-align: center;">{{record.person_called}}</td>
                    <td  style="text-align: center;">{{record.person_relation}}</td>
                    <td  style="text-align: center;">{{record.phone_number}}</td>
                    <td  style="text-align: center;">{{record.absent_reason_name}}</td>
                    <td  style="text-align: center;">{{record.remarks}}</td>
                    <td  style="text-align: center;"><a href="#" v-on:click="editAbsentFollowbackRecord($index)" data-toggle="modal" data-target="#absent-followback-edit"> Edit </a></td>
                    
                </tr>
            </tbody>
        </table>
        
    </div>
</div>

<script src="/static/js/jquery-ui.min.js"></script>
<script src="/static/js/jquery.plugin.min.js"></script> 
<script src="/static/js/jquery.datepick.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue/latest/vue.js"></script>
<script src="/static/js/csrftoken.js"></script>
<script src="/static/js/jquery.TableCSVExport.js"></script>

<script type="text/javascript">

    var absentFollowbackListAPiUrl = "/student/api/absent/followback/list/11/";
    var absent_reason = jQuery.parseJSON('[{"model": "studentprofile.absentreason", "pk": 1, "fields": {"created": "2016-05-08T06:09:42.410Z", "modified": "2016-05-08T06:09:42.410Z", "reason_name": "sick"}}, {"model": "studentprofile.absentreason", "pk": 2, "fields": {"created": "2016-05-08T06:09:42.416Z", "modified": "2016-05-08T06:09:42.416Z", "reason_name": "arrived late"}}, {"model": "studentprofile.absentreason", "pk": 3, "fields": {"created": "2016-05-08T06:09:42.419Z", "modified": "2016-05-08T06:09:42.419Z", "reason_name": "work at home"}}, {"model": "studentprofile.absentreason", "pk": 4, "fields": {"created": "2016-05-08T06:09:42.423Z", "modified": "2016-05-08T06:09:42.423Z", "reason_name": "public holiday"}}]');
    var profile_value = false;
    
</script>
<script type="text/javascript" src="/static/js/student/student-followback.js"></script>

> absent-followback.js file

$(function() {
    $( "#datepicker" ).datepick({dateFormat: 'yyyy-mm-dd'});
});

$('#csv_export').click(function (e) {
    e.preventDefault();
    $('#absent-list').TableCSVExport({
        delivery: 'download',
        filename: 'absent-list(' + $( "#datepicker" ).val() + ').csv'
    });
});

var vm = new Vue({
        el: 'body',
        data: {
            absent_followback_records: [],
            followbackRecordIndex: 'off',
            absentReasonList: absent_reason,
            loading: false,
            currentData: {},
            profile: profile_value,
            listApiUrl: absentFollowbackListAPiUrl
        },
        methods: {
            populateData: function(api_url){
                var self = this;
                $.get(api_url, function(data){
                    self.absent_followback_records = data;
                    self.loading = false;
                });
            },
            getAbsentFollowbackRecord: function () {
                var self = this;
                self.loading = true;
                var date = $( "#datepicker" ).val();
                var api_url = self.listApiUrl + '?date=' + date;
                self.populateData(api_url);
            },
            getProfileAbsentFollowbackRecord: function (event) {
                var self = this;
                self.loading = true;
                var expanded = $(event.target).attr('aria-expanded');
                if (expanded == 'false'){
                    $(event.target).html('Hide Details');
                    var studentId = $(event.target).attr('studentId');
                    var api_url = self.listApiUrl + '?student_id=' + studentId;
                    self.populateData(api_url);
                }
                else{
                    $(event.target).html('Show Details');
                }
            },
            editAbsentFollowbackRecord: function (followbackRecordIndex) {
                var self = this;
                self.currentData = self.absent_followback_records[followbackRecordIndex];
                self.followbackRecordIndex = followbackRecordIndex;
            },
            updateAbsentFollowbackRecord: function (followbackRecordIndex){
                var self = this;
                var updateData = self.currentData;
                var absent_date = updateData.date;
                var student_id = updateData.student;
                var post_url = updateData.update_url;
                var person_called = updateData.person_called;
                var person_relation = updateData.person_relation;
                var phone_number = updateData.phone_number;
                var absent_reason = updateData.absent_reason;
                var remarks = updateData.remarks;
                if (person_called){
                    var data = {
                        student: parseInt(student_id),
                        date: absent_date,
                        person_called: person_called,
                        person_relation: person_relation,
                        phone_number: phone_number,
                        absent_reason: parseInt(absent_reason),
                        remarks: remarks
                    };
                    $('#updateAbsentFollowback').html('<i class="fa fa-spinner fa-spin"></i> Saving').attr('class', 'btn btn-primary disabled');
                    $.ajax({
                        url: post_url,
                        type: "PUT",
                        data: JSON.stringify(data),
                        dataType: 'json',
                        contentType: "application/json",
                        success: function(responseData) {
                            $('#updateAbsentFollowback').html('Save').attr('class', 'btn btn-success');
                            if (self.profile == true){
                                api_url = self.listApiUrl + '?student_id=' + student_id;
                                self.populateData(api_url);
                            }
                            else{
                                self.getAbsentFollowbackRecord();
                            }
                        },
                        error: function( xhr, status, errorThrown ) {
                        console.log(errorThrown);
                        }
                    });
                }
            }

        },
        ready() {
            if (this.profile != true){
                this.getAbsentFollowbackRecord();
            }
        }
    })

Javascript Solutions


Solution 1 - Javascript

You can use script tag in this way and it will work fine. I was facing the same problem when I used <script></script> tag without specifying its type. After using the type attribute Vue did not warn me for critical error:

<script type="application/javascript"> 
    // your code
</script>

Solution 2 - Javascript

I think the answer is in you question title. Just get rid of all the <script> tags in the template, put them outside of the template.

In this case you are using body as the template and you are putting scripts inside your template (body)

The easy solution is to change the el: 'body' to el: '#wrapper' and edit your html to

<body>
<div id="wrapper">
...
</div>
<script ... >
<script ... >
</body>

Solution 3 - Javascript

Make sure you have a closing tag on your root element. I just spent the last 6 hours systematically removing things and pulling my hair out. Turns out I had deleted my closing at some point and Vue was interpreting

Solution 4 - Javascript

a pair of mismatched tags (div, span) can cause this error.

<div id="app">
    <div>{{ a }} </span>
</div>

Solution 5 - Javascript

It is because of script tag in your app scope. In my case it was because of google captcha that was in my scope. Google captcha iframe contains script tag

Solution 6 - Javascript

VueJs doesn't allow

Solution 7 - Javascript

My suggestion is a little specific, as I'm using Vue JS v2 in conjunction with jQuery v3.

I'm using jQuery to load the instance of my application with something simple like this:

$(() => {

  new Vue({
    name: 'MyApp',
    el: '#app' // which is my main HTML element for my entire page app
  });

});

So, this won't initiate until the entire document is loaded.

In my footer, I'm changing any offending script tags with this before the entire document is loaded, but after my closing main HTML tag:

$('main script:not([type="application/javascript"])').attr('type', 'application/javascript');

This did the trick for me without having to parse any output from offending tags and doing anything more extravagant.

This can be extrapolated out, using the native document selectors if you're not using jQuery, like my example.

Solution 8 - Javascript

(Edit first check for mismatched/unclosed tags within your template, as others have said. Vue can be very picky with that)

Might be a simple as an explicit closure of the component's tag:

Version: [email protected]

Error there:


...body html...

<bme-form-projval
show_debug_elements="Y"
form_name="batchform"
>

...body html...

still there:

<bme-form-projval
show_debug_elements="Y"
form_name="batchform"
/>

Error solved:

<bme-form-projval
show_debug_elements="Y"
form_name="batchform"
>

</bme-form-projval>

Solution 9 - Javascript

Ensure all HTML Tags in the page are opened and closed properly.

Solution 10 - Javascript

Although changing "script" to "script type="application/javascript"" makes the warning disappeared, it causes the page not to finish loading. Therefore, it would not be a good idea to use it!

Solution 11 - Javascript

This code generate this error too!

<!--[if lte IE 8]>
    <div>...</div>
<![endif]-->

Solution 12 - Javascript

Check your browser source code, maybe something else has been added to the framework you are using. In my case, I did not remove the rails layout template.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRaj SubitView Question on Stackoverflow
Solution 1 - JavascriptPoodeView Answer on Stackoverflow
Solution 2 - JavascriptgurghetView Answer on Stackoverflow
Solution 3 - JavascriptinnominataView Answer on Stackoverflow
Solution 4 - JavascriptRm558View Answer on Stackoverflow
Solution 5 - JavascriptHlib LiapotaView Answer on Stackoverflow
Solution 6 - JavascriptVkash PoudelView Answer on Stackoverflow
Solution 7 - JavascriptErutan409View Answer on Stackoverflow
Solution 8 - JavascriptJL PeyretView Answer on Stackoverflow
Solution 9 - Javascriptjames aceView Answer on Stackoverflow
Solution 10 - JavascriptHabib SeifzadehView Answer on Stackoverflow
Solution 11 - JavascriptOmar ArturoView Answer on Stackoverflow
Solution 12 - JavascriptDavid tsangView Answer on Stackoverflow