【问题标题】:Why is my data undefined after mapping although the mapping was successful?为什么映射成功后我的数据未定义?
【发布时间】:2020-11-30 22:34:18
【问题描述】:

我有一个返回 observable 的函数

  getData(){
    return this.http.get<{mat: any[], mat_auf: any[], mat_lok: any[], auf_an: any[]}>(this.authUrl + 'get/mat-data').pipe(
      map(({mat, mat_auf, mat_lok, auf_an}) => {
        console.log("AuthService", {mat, mat_auf, mat_lok, auf_an}); // correct data format
        mat.map(mat => {
          this.matAdapter.adapt(mat);
        });
        mat_auf.map(mat_auf => {
          this.mat_aufAdapter.adapt(mat_auf);
        });
        mat_lok.map(lok => {
          this.lokAdapter.adapt(lok)
        });
        auf_an.map(an => {
          this.aufAdapter.adapt(an)
        });
      })
    );
  }

如果我查看控制台,适配器的转换工作正常,但是当我尝试订阅另一个组件中的 Observable 时,我得到未定义:

ngOnInit(){
    this.authSrv.getData().subscribe(res => console.log(res)) // res is undefined but why?
}

适配器如下所示:

@Injectable({
    providedIn: "root"
})
export class MatAdapter implements Adapter<Mat>{
    adapt(mat: any): Mat {
        return new Mat(mat.ID, mat.name, mat.location);
    }
}

正如我所说,适配器工作正常,因为在控制台中记录了正确的对象。 但是,当我尝试订阅 observable 时,为什么数据未定义? 我想我用错了地图功能。

感谢任何帮助。如果需要更多信息,请发表评论。 谢谢

【问题讨论】:

  • console.log() 总是返回undefined!!!所以如果你映射到console.log(something)log something* but *produce* the value undefined`的值。
  • @VLAZ 嘿,我刚刚使用了 console.log 来查看转换是否正确。但是如果我省略了 console.log 部分,数据仍然是未定义的。我改变它以避免误解。谢谢!
  • 哦,另外,在带有.map 的第一个块中,您甚至没有return 语句。所以当getData()被调用时,它会调用`this.http.get().pipe(map())`但是没有映射结果。隐式返回总是undefined。 “嘿,我刚刚使用了 console.log 来查看转换是否正确”请不要使用map 进行简单的迭代。使用forEach 或实际循环。一开始就极具误导性。
  • 我建议阅读Is performing a mapping operation without using returned value an antipattern?,因为这正是这里的问题 - 对某些数据执行映射而不返回任何内容。
  • 作为特定于rxjs 的附加提示:如果您想在不更改可观察对象的情况下对可观察对象执行副作用,rxjs 提供了tap 运算符。这将替换您示例中的外部地图。

标签: angular typescript rxjs mapping observable


【解决方案1】:

如果你给一个返回类型为 void 的函数赋值,你会得到 undefined。

function addAndLog(x,y): void {
  console.log(`x + y = ${x + y}`);
}

const added = addAndLog(8,10);
consle.log(added);

// Output: 
// "8 + 10 = 18"
// undefined

我希望您能理解,即使我记录了两个数字相加,但这并不意味着 added 被赋予了该值。 addAndLog 不返回值,因此 added 将始终为 undefined

您的映射操作将它收到的每个值映射到未定义。你给map 的函数被运行并且它的返回值被分配为映射 值。在这种情况下,您永远不会返回任何东西。


重写工作:

function addAndLog(x,y): void {
  console.log(`x + y = ${x + y}`);
  return x + y;
}

const added = addAndLog(8,10);
consle.log(added);

// Output: 
// "8 + 10 = 18"
// 18

【讨论】:

    猜你喜欢
    • 2018-05-01
    • 1970-01-01
    • 2019-01-06
    • 2019-03-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多