It looks like your MainView's $el is empty and you haven't specified a template for it to use either. So, in essence, when you're referencing "this" in loginModal, it's attempting to find the first DOM element that matches your jquery selector -- but it's looking for it inside the view $el which is empty. When you attempt it from the console, "this" becomes the global document scope and so you find it.
My suggestion would be to load your mainview's html into a underscore template and render it inside the standard render function from backbone. It would probably look something like this:
define([
'jquery',
'underscore',
'backbone',
'bootstrap',
'!text/path_to_html_templates/MainView.html'
], function ($, _, Backbone, Bootstrap, mainViewTemplate) {
var MainView = Backbone.View.extend({
$el: $('.container'),
template: _.template(mainViewTemplate),
events: {
'click .nav-link.login': 'loginModal'
},
loginModal: function() {
this.$('#login-email, #login-password').val('');
this.$('#login-modal .alert').addClass('hide');
this.$('#login-modal').modal();
},
render: function() {
this.$el.html(this.template());
}
});
return MainView;
});
I don't know enough of your UI structure to help you much more than that but hopefully that at least gives you a start.