Как извлечь только определенные свойства json, возвращаясь в качестве наблюдаемого с помощью rxjs

#json #angular #typescript #rxjs #rxjs-observables

#json #angular #typescript #rxjs #rxjs-наблюдаемые

Вопрос:

Например, это json, который я получаю,

 {
    "events": [...
    ],
    "total": 12341,
    "students": [
        {
            "id": 1,
            "first_name": "John",
            "last_name": "Apple"
        },
        {
            "id": 2,
            "first_name": "Bob",
            "last_name": "Banana"
        },
        {
            "id": 3,
            "first_name": "Charles",
            "last_name": "Carrot"
        }
    ]
}
  

И я хочу преобразовать данные в следующую форму и вернуть их как наблюдаемое

 [
    {
        "first_name": "John",
        "last_name": "Apple"
    },
    {
        "first_name": "Bob",
        "last_name": "Banana"
    },
    {
        "first_name": "Charles",
        "last_name": "Carrot"
    }
]
  

Я пробовал следующее, но оно возвращает undefined.

 getStudentsName(): Observable<any> {
    const requestUrl = this.rootURL   `students/`;
    let studentsInfo = this.http.get<any>(requestUrl).pipe(map(o => o.students));
    return studentsInfo.pipe(map(students => {students.first_name, students.last_name}));
  }
  

возвращает неопределенный при подписке на наблюдаемый

 this.getStudentsInfoService.getStudentsName()
      .subscribe((result) => console.log('here', result));
  

Ответ №1:

Ваша проблема в том, что students — это массив, но вы обрабатываете его как объект. Вам нужно добавить вложенную карту: 1 для rxjs, 1 для массива

 return studentsInfo.pipe(
  map(studentsArray => studentsArray.map(student => ({
    first_name: student.first_name,
    last_name: student.last_name
  }))),
);
  

PS.: Использование типов вместо any показало бы вам это. Ни вы, ни другие респонденты не заметили эту проблему из-за отсутствия ввода.

Ответ №2:

Похоже, он не может найти students . Попробуйте это :

 return studentsInfo.pipe(map(s => { return {
  first_name: s.first_name,
  last_name: s.last_name,
}}));
  

Комментарии:

1. о да, я только что это понял, но он также возвращает undefined

2. Вам нужно либо указать возврат, либо заключить {} внутренние круглые скобки ({}) . В противном случае он будет обрабатываться как блок кода, а не как объект.

3. Я получаю эту ошибку после изменений, синтаксический анализатор ожидал найти ‘}’, соответствующий токену ‘{‘ здесь.

4. Упс, похоже, в нем отсутствовал набор фигурных скобок

5. о, теперь он возвращает значение, но теперь first_name: undefined, last_name: undefined

Ответ №3:

Вот короткий фрагмент кода.

 const object = {
    "total": 12341,
    "students": [
        {
            "id": 1,
            "first_name": "John",
            "last_name": "Apple"
        },
        {
            "id": 2,
            "first_name": "Bob",
            "last_name": "Banana"
        },
        {
            "id": 3,
            "first_name": "Charles",
            "last_name": "Carrot"
        }
    ]
}

let arr: any = [];
object.students.forEach(person => arr.push(
    {
        "first_name": person.first_name,
        "last_name": person.last_name
    }))

console.log(arr)


    [LOG]: [{ "first_name": "John", "last_name": "Apple" }, 
{ "first_name": "Bob", "last_name": "Banana" }, { "first_name": "Charles", "last_name": "Carrot" }] 
  

Вы можете перебирать учеников с помощью цикла foreach, а затем создавать новый json, который затем вставляется в ваш новый массив

 this.http.get<any>(requestUrl).pipe(map(o => o.students.foreach(person => arr.push({
...}));
  

Комментарии:

1. forEach-push Подход является плохой практикой и действительно должен быть заменен на map

Ответ №4:

Проблема

Проблема в том, как вы возвращаете свой наблюдаемый

Давайте разберем код

 let studentsInfo = this.http.get<any>(requestUrl).pipe(map(o => o.students));
  

В приведенном выше studentsInfo будет типа Observable<any>

Следующая строка приведена ниже

 return studentsInfo.pipe(
  map(students => {
    students.first_name, students.last_name
  }
));
  

Давайте посмотрим на следующий раздел

 {
  students.first_name, students.last_name
}
  

В этой части раздела фактически нет оператора return, поэтому по умолчанию javascript возвращает undefined!

Решение

Чтобы использовать функцию arrow без оператора return, вам нужно будет обернуть {} внутри () like ниже

 students => ({ })
  

Ниже будет работать

 getStudentsName(): Observable<any> {
  return this.http.get<any[]>(`${this.routeURL}/students`).pipe(
    map(o => o.students));
  }