Having trouble retrieving the JSON data from the getNutrition() service method using a post request to the Nutritionix API. Just started exploring APIs and using Angular

When attempting to contact the service, this.food is recognized as a string

import { Component, OnInit } from '@angular/core';
import { ClientService } from '../../services/client.service';
import { Client } from '../../models/Client';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { FlashMessagesService } from 'angular2-flash-messages';
import { Route } from '@angular/compiler/src/core';
import { Foods } from '../../models/Foods';

@Component({
  selector: 'app-client-info',
  templateUrl: './client-info.component.html',
  styleUrls: ['./client-info.component.css'],
})
export class ClientInfoComponent implements OnInit {
  id: string;
  client: Client;
  food: string;
  foods: Foods;
  
  constructor(
    private clientservice: ClientService,
    private router: Router,
    private route: ActivatedRoute,
    private flashmessage: FlashMessagesService
  ) {}

  ngOnInit(): void {
    this.id = this.route.snapshot.params['id'];
    this.food = this.route.snapshot.params['food'];
    this.clientservice.getClient(this.id).subscribe((client) => {
      this.client = client;
    });
    this.clientservice
      .getNutrition(this.food)
      .subscribe((foods) => (this.foods = foods.foods));
  }
}

Having trouble extracting "foods" from the JSON in the getNutrition function and unsure if it's being done correctly. At the same time, encountering HTTP request errors. Postman testing went smoothly, but the body sent on Postman was in JSON format, could that be causing the issue?

Here is the related service:

import { Injectable } from '@angular/core';
import {
  AngularFirestore,
  AngularFirestoreCollection,
  AngularFirestoreDocument,
} from '@angular/fire/firestore';
import { Observable } from 'rxjs';
import { Client } from '../models/Client';
import { map, catchError } from 'rxjs/operators';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { ThrowStmt } from '@angular/compiler';

@Injectable({
  providedIn: 'root',
})
export class ClientService {
  clientCollections: AngularFirestoreCollection<Client>;
  clientDoc: AngularFirestoreDocument<Client>;
  clients: Observable<Client[]>;
  client: Observable<Client>;
  foods: Observable<any>;
  constructor(private firestore: AngularFirestore, private http: HttpClient) {
    this.clientCollections = firestore.collection('clients');
  }

  getNutrition(query: string): Observable<any> {
    let url: string = 'https://trackapi.nutritionix.com/v2/natural/nutrients';
    let headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'x-app-id': 'xxx',
      'x-app-key': 'xxx',
    });
    let options = { headers: headers };
    this.foods = this.http.post(url, query, options).pipe(
      map((req) => {
        console.log(req);
      })
    );
    return this.foods;
  }
}

This is the JSON data received from Postman:

{
    "foods": [
        {
            "food_name": "apple",
            "brand_name": null,
            "serving_qty": 1,
            "serving_unit": "medium (3\" dia)",
            "serving_weight_grams": 182,
            "nf_calories": 94.64,
            "nf_total_fat": 0.31,
            "nf_saturated_fat": 0.05,
            "nf_cholesterol": 0,
            "nf_sodium": 1.82,
            "nf_total_carbohydrate": 25.13,
            "nf_dietary_fiber": 4.37,
            "nf_sugars": 18.91,
            "nf_protein": 0.47,
            "nf_potassium": 194.74,
            "nf_p": 20.02,
            "full_nutrients": [
               ...
             ]
             ...
    ]
}

Edit: Here is my Food.ts file in the models directory:

export interface Foods {
  nf_total_fat?: number;
  nf_saturated_fat?: number;
  nf_cholesterol?: number;
  nf_sodium?: number;
  nf_total_carbohydrate?: number;
  nf_dietary_fiber?: number;
}

Answer №1

I believe the issue arises because you are not returning a response in the map function. Also, you have added the req argument to map instead of res, as this operator is mapping the response and not the request.

this.foods = this.http.post(url, query, options).pipe(
  map((res) => {
    console.log(res);
    return res; 
  })
);

Another issue is that you are sending the body as a string rather than an object. Therefore, you should replace

this.http.post(url, query, options)
with
this.http.post(url, { query }, options)
.

getNutrition(query: string): Observable<any> {
    let url: string = 'https://trackapi.nutritionix.com/v2/natural/nutrients';
    let headers = new HttpHeaders({
      'Content-Type': 'application/json',
      'x-app-id': 'xxx',
      'x-app-key': 'xxx',
    });
    let options = { headers: headers };
    this.foods = this.http.post(url, { query }, options).pipe(
      map((req) => {
        console.log(req);
      })
    );
    return this.foods;
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Angular | Creating a template reference variable for a division element

Utilize the code provided to create 4 divs each sized at 200x200. In order to apply a specific class to a div when the mouse is hovering over it (without affecting the other three), you need to follow these steps: <style> div {height: 200px; wid ...

Typescript Syntax for Inferring Types based on kind

I'm struggling to write proper TypeScript syntax for strict type inference in the following scenarios: Ensuring that the compiler correctly reports any missing switch/case options Confirming that the returned value matches the input kind by type typ ...

What is the Reason for TypeScript's Inability to Verify the Type of Dynamic Key Object Fields?

How come TypeScript allows the declaration of seta even though it doesn't return objects of type A? type A = { a: '123', b: '456' } // Returns copy of obj with obj[k] = '933' function seta<K extends keyof A> ...

Issue observed with the functionality of checkAll and uncheckAll after a user interacts with a single checkbox

After completing an Angular course on Udemy, I decided to implement a custom checkbox in my Angular app. However, I encountered an issue where the UI was not updating properly when using checkAll and uncheckAll functions after the user interacted with an i ...

Encountering a style-loader error while trying to upgrade to Angular 15 using @angular-builders/custom-webpack

Check out my demo repository at the following link: https://github.com/OrShalmayev/style-loader-error After upgrading my Angular project from version 12 to 15, I encountered an issue with my angular.json file configuration: "architect": { &q ...

Ways to display an error message in Angular 8 when entering anything other than numbers in a text box

In my Angular 8 application, I have a text box that only allows the user to type numbers. If they try to type an alphabet or special character, it should display an error message below the text box. The error message should disappear once the user starts ...

Guide to waiting for an event to finish in Angular

My component features a scorebar positioned on the left side, with game logic being managed by a separate game service. When a new player joins, I need to temporarily hide the scorebar, update the players array in the game.service, and then display the sco ...

Child component in Angular 17 failing to pass null params to app root

I'm utilizing Angular 17 with SSR. When routing to: en/home/1, I try injecting ActivatedRoute. However, I am unable to retrieve the params from the child component or the app root component. How can I get the params from the child component (app-menu ...

How to access properties of objects within an array in Angular 4

Is there a method to call only the $values from each rate record in my array that I want to read? https://i.sstatic.net/MT2XK.png This is what I have done to access this array: async ngOnInit() { this.product$ = await this.reviewService.getReview(th ...

Utilizing JavaScript files within Angular2 components: A guide

I need to insert a widget that runs on load. Typically, in a regular HTML page, I would include the script: <script src="rectangleDrawing.js"></script> Then, I would add a div as a placeholder: <div name="rectangle></div> The is ...

Scope management of Angular 6 fields within nested anonymous functions

While working with OpenLayers, I have encountered an issue accessing my fields within inner scopes of function calls. Here is an example: method() { this.myField.on('click', function (args) { this.myFieldThatIsntInScope(evt.pixel, fu ...

Is there a way to determine which response corresponds to each request when hitting the same endpoint multiple times?

When making multiple requests to an API endpoint, how can I differentiate the response for each specific request? For example, if a user clicks the upload button three times, how can I track each request individually? ...

Locate the nearest upcoming date and time to today's date in the JSON response

I am currently working with an API that provides a response containing the `start_time` field in JSON format. My goal is to extract the ID from the JSON object whose next date time is closest to the current date and time, excluding any dates from the past. ...

best practices for running callbacks in sequence within Angular

Seeking a solution to ensure Angular waits for data fetching to complete before proceeding with execution in ngOnInit: fetchData() { console.log('2') this.http.get("http://jsonplaceholder.typicode.com/users").subscribe( (data) =&g ...

Is there a more efficient solution for incorporating undefined and null into a type apart from developing a custom generic function?

Often in programming, we encounter methods where one or more parameters can be null or undefined (sometimes both with derived types). This can result in long method signatures like this: doThing( user: User | undefined | null, thing: Thing | undefined ...

Modifying the menu with Angular 4 using the loggedInMethod

Struggling to find a solution to this issue, I've spent hours searching online without success. The challenge at hand involves updating the menu item in my navigation bar template to display either "login" or "logout" based on the user's current ...

Using the css function within styled-components

Struggling with implementing the media templates example from the documentation and figuring out how to type the arguments for the css function in plain JS: const sizes = { desktop: 992 } const media = Object.keys(sizes).reduce((acc, label) => { ...

Utilizing Angular with the development environment of Visual Studio 2015

Having trouble setting up my angular 2 application in visual studio 2015 (with update 1). The typescript compile is throwing an error - it says 'Cannot find module '@angular/core' at import { NgModule } from '@angular/core';. I eve ...

OneGraph and Graphql Codegen produce enums with numerical representations

After migrating my project's codebase from using the direct Headless Wordpress GraphQL endpoint to OneGraph for Google+Facebook Business support, I encountered an error related to apollo referencing the output codegen. Here is the specific error messa ...

What is the best way to create a custom hook that updates in response to changes in state?

My situation involves a custom hook that handles a specific state variable. After making changes to the state, it doesn't update right away. To solve this issue, I need to subscribe to it using useEffect. The challenge is that I can't directly ...