未捕获的类型错误:无法读取未定义的属性“ajax”

Posted

技术标签:

【中文标题】未捕获的类型错误:无法读取未定义的属性“ajax”【英文标题】:Uncaught type error: Cannot read property 'ajax' of undefined 【发布时间】:2021-06-05 20:20:05 【问题描述】:

我是 ember.js 的新手,这是我的第一个应用程序。我想建立一个登录表单,如果用户输入了正确的电子邮件和密码,他应该被转换到主页。我不确定是否应该将 Ember Data 用于登录部分,但我在某处读到 Ember Data 不适合这个特定的登录任务,所以我应该发出 ajax 请求(这个假设正确吗?)。但是,当我提出请求时,我收到以下错误:

未捕获的类型错误:无法读取 LoginComponent.logUser 处未定义的属性“ajax”

我已经在登录组件类中发出了 http 请求,但我不确定是否应该在这部分使用控制器,因为在我看到的所有示例中,请求都是在控制器中处理的。但是,我不知道如何在单击登录按钮时使用登录控制器。

所以除了如何处理我遇到的错误之外,我还有几个问题:

    我应该使用 Ember Data(如果是的话如何)来完成登录任务,还是应该使用 ajax 方法? 控制器和组件(类)有什么区别,我应该在什么时候使用它们,用户点击处理数据或发出请求?

提前感谢您的帮助!

这是我的代码

login.hbs - 模板:

<h1 id="pageTitle">Log In</h1>
<Login/>

login.hbs - 组件:

<form on "submit" this.logUser id="login">
    <label class='formElement labelLogin'>Email :</label><br>
    <Input class='formElement input' @value=this.email/><br>
    <label class='formElement labelLogin'>Password :</label><br>
    <Input class='formElement input' @value=this.password/><br>
    <button id="loginButton" class='button formElement' type="submit">Log In</button> 
</form>

login.js - 组件类

import Component from '@ember/component';
import  action  from "@ember/object";
import  tracked  from "@glimmer/tracking";

export default class LoginComponent extends Component
  @tracked email;
  @tracked password;

  @action
  logUser()
        let userData = JSON.stringify(
            'email' : this.email,
            'password' : this.password
        );
        Ember.$.ajax(
            url : 'https://gara6.bg/auto-api/users/login',
            type : 'POST',
            dataType: 'json',
            data : userData,
        ).then(() => 
            alert('Logged In');
            this.transitionToRoute('home');
        ).catch(function(error)
            alert(`Error: $error`);
        );
    

routes.js:

import EmberRouter from '@ember/routing/router';
import config from 'gara6/config/environment';

export default class Router extends EmberRouter 
  location = config.locationType;
  rootURL = config.rootURL;


Router.map(function () 
  this.route('login');
  this.route('home');
);
  

这是使用 fetch 编辑的 login.js 组件类:

import Component from '@ember/component';
import  action  from "@ember/object";
import  tracked  from "@glimmer/tracking";

export default class LoginComponent extends Component
  @tracked email;
  @tracked password;

  @action
  logUser()
        let userData = 
            'email' : this.email,
            'password' : this.password
        ;
        let fetchObject = 
            method: 'POST',
            headers : 
                'Content-type' : 'application/json', 
            ,
            body : JSON.stringify(userData),
        ;
        fetch('https://gara6.bg/auto-api/users/login',fetchObject)
        .then(response => 
            alert(response.status);
            alert(response.statusText);
            if(!response.ok)
                alert('Network response was not ok');
            
            alert(response.json());
            return response.json();
            // alert('Logged In');
            // this.transitionToRoute('home');
        ).then(data =>
            alert(data);
        ).catch(error => 
            alert(`There has been a problem with your fetch operation: $error`);//This is the only alert that shows up.
        );
        console.log(userData);
    

Here I have clicked on the button and the alert shows up

2:This is the request data for the red login request. Surprisingly, there is request payload which matches the content of my text fields

Here is what is shown when I click OK on the alert. The number of requests have changed

This is the request data for the newly shown login request (note his type is GET)

【问题讨论】:

reg, ajax:如果您使用的是最新版本 (Octane),则默认禁用 JQuery 集成。您可以在config/optional-features.json 文件中启用该功能。检查此以了解有关可选功能的更多信息:guides.emberjs.com/release/configuring-ember/optional-features。或者,您可以使用包含在蓝图本身中的ember-fetch 即使你想使用 jQuery 而不是原生的 fetch,我还是建议显式导入 jquery 而不要依赖 Ember 集成。 Ember 的 jQuery 集成很可能在中短期内被弃用和删除。将 jQuery 作为任何其他依赖项导入应该可以长期有效。但我认为原生fetch是前进的方向。 您也绝对不应该使用 ember-data 进行登录,但您可以查看ember-simple-auth。但是注册fetch 是要走的路。 @jelhan,你的意思是,如果我按照 Gokul Kathirvel 的建议在 config/optional-features.json 中启用 jQuery,这在未来将不会有什么用处。所以我应该将它作为依赖项导入。 @Lux,@jelhan,@Gokul Kathirvel ,正如你们所有人建议的那样,我尝试使用 fetch 发出请求。我不知道我可以将 fetch 用于发布请求。但是,该请求仍然无效。当我在 chrome 开发人员工具的网络选项卡中检查我的请求时,我看到了一个 GET 请求。为什么会这样? 【参考方案1】:

所以在我朋友的帮助下,POST请求转换为GET的问题已经解决了。原来问题出在表单元素上,默认情况下它具有预定义的功能,因此解决方案是使用 e.preventDefault() 阻止它们。

这是已经工作的代码:

import Component from '@ember/component';
import  inject as service  from '@ember/service';
import  action  from "@ember/object";
import  tracked  from "@glimmer/tracking";

export default class LoginComponent extends Component
  @tracked email;
  @tracked password;
  @service router;
  
  @action
  logRequest()
    let result=0;
    let userData = 
        'email' : this.email,
        'password' : this.password
    ;
    let fetchObject = 
        method: 'POST',
        headers : 
            'Content-type' : 'application/json', 
        ,
        body : JSON.stringify(userData),
    ;
    fetch('https://gara6.bg/auto-api/users/login',fetchObject)
        .then(response => 
            if(!response.ok)
                throw new Error('Network response was not ok');
            
            result=1;
        )
        .catch(error => 
            alert(`There has been a problem with your fetch operation: $error`);
        );
    return result;
  


  @action
  logUser(e)
    e.preventDefault();
        let result = this.logRequest;
        if(result)
            alert('Logged in');
            this.router.transitionTo('home');
        
        else
            alert('Not logged in');
        
    

【讨论】:

以上是关于未捕获的类型错误:无法读取未定义的属性“ajax”的主要内容,如果未能解决你的问题,请参考以下文章

未捕获的类型错误:无法读取 React ajax 调用中未定义的属性“then”?

未捕获的类型错误:无法读取未定义的属性“长度”

未捕获的类型错误:无法读取未定义的属性 toLowerCase

未捕获的类型错误:无法读取未定义的属性“createDocumentFragment”

jstree:未捕获的类型错误:无法读取未定义的属性“孩子”

数据表:未捕获的类型错误:无法读取未定义的属性“长度”?