Having trouble with API calls in TypeScript when receiving a single object as a response?

Currently, I'm faced with a task that requires me to fetch 10 Chuck Norris jokes from an API. While I managed to accomplish this part, I'm struggling with the second part of the task, which involves retrieving a random joke every 5 seconds.

// Fetch jokes based on quantity
getJokes(amount) {
const jokeArray = [];
let randomJokeArray;
if (amount > 1){
  this.http.get('http://api.icndb.com/jokes/random/' + amount).subscribe(data => {
    // Check if API call was successful
    if (data["type"] === 'success'){
        for(let i = 0; i <= data["value"].length; i++){
          jokeArray.push(data["value"][i]);
        }
    } else {
      console.warn("API Call 'getJokes' failed");
    }
  });
} else {
  this.http.get('http://api.icndb.com/jokes/random/' + amount).subscribe(data => {
    // Check if API call was successful
    if (data["type"] === 'success'){
      randomJokeArray = data["value"][0];
      console.log(randomJokeArray);
    } else {
      console.warn("API Call 'getJokes' failed");
    }
  });
}

    if (amount > 1){
      // Return the jokeArray
      return of(jokeArray);
    } else {
      return of(randomJokeArray);
    }

}

The issue is that randomJokeArray always returns as undefined.

This function is implemented within a service, and as someone relatively new to TypeScript and Angular, it's likely that I am using it incorrectly. Could someone please guide me on how to retrieve just one joke from the API?

If I replicate the API call for fetching 10 jokes, it works fine, but when trying to get only one joke, I face the following problem.

From the main file

this.configService.getJokes(1).subscribe(j => this.randomJokeArray = j);

From the service file

for(let i = 0; i <= data["value"].length; i++){
    randomJokeArray.push(data["value"][i]);
}

return of(randomJokeArray);

https://i.sstatic.net/yRM6c.png

Answer №1

There are three issues that need to be addressed in your code:

  1. The first issue is that your component is subscribing to a Subscription, not an Observable. To fix this, you should use the map operator on the response returned by http instead of subscribing. This way, you can return an Observable to your component.

    this.http.get('http://api.icndb.com/jokes/random/' + amount).pipe(map(data => {
       // Test to see if call was successful
                 .........................................
    }));
    
  2. The main issue is that you are not waiting for the asynchronous execution to be completed.

    To resolve this, move your if(amount > 1){...} code inside http.get.map().

    return this.http.get('http://api.icndb.com/jokes/random/' + amount).pipe(map(data => {
        // Test to see if call was successful
        if(data["type"] === 'success'){
          randomJokeArray = data["value"][0];
          console.log(randomJokeArray);
        } else {
          console.warn("API Call 'getJokes' was unsuccessful");
        }
    
        if(amount > 1){
            // Return the jokeArray
            return of (jokeArray);
        } else {
            return of (randomJokeArray);
        }
    }));
    
  3. Add a return statement before http.get.map().

    return this.http.get('http://api.icndb.com/jokes/random/' + amount).pipe(map(data => {
           // Test to see if call was successful
           .........................................
    }));
    

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

Is there a way to dynamically apply styles to individual cells in a React Table based on their generated values?

I'm having trouble customizing the style of a table using react table, specifically changing the background color of each cell based on its value. I attempted to use the getProps function in the column array as suggested by the react table API documen ...

How come my form submission continues to refresh the page?

I am new to the world of ajax and have a basic understanding of jQuery. Nonetheless, I am facing challenges while testing a simple ajax script. I have gone through similar questions for help, but unfortunately, I haven't been able to find a solution y ...

Tips on incorporating a past random selection into an RPG lifepath generator's current random selection process

Currently, I am in the process of creating a JavaScript version of a basic "life path generator" commonly seen in pen and paper RPGs. The generators I have been working on are inspired by the structure provided at this link: However, I am encountering dif ...

The CSS legend for a FLOT plot chart is being unexpectedly replaced

I am currently exploring the FLOT plot tool and facing difficulty with the legend display. It seems that the CSS styling for the legend is somehow being overridden in my code, resulting in an undesirable appearance of the legend: Even when I try to specif ...

"Utilizing Primeng's dynamic functionality to create a selected p-tab

Utilizing the TabView module from primeng, I have created a dynamic tab where only the last tab remains static. The property used is 'selected', and for the dynamic tab, it is set as [selected]="'tab' + $index", where $index represents ...

Nested *ngFor Loop in Angular 2

I am facing an issue with my classes Produkt and Werbedaten. The werbedaten class includes a produckt array. My goal is to display a werbedaten array containing the Produkts array using *ngFor export class Produkt { public artikelNummer: number; p ...

Once the Angular project has been initialized, the Button disable attribute cannot be modified

In my Ionic-Angular project, I am creating registration pages where users input their information in multiple steps. For each step, there is a button that remains disabled until the correct information is entered. An issue arises when transitioning to the ...

Encountering an issue with Apollo Express GraphQL: Error message stating that the schema must have distinct type names, yet it contains more than one type named "DateTime"

After importing the applyMiddleware library from 'graphql-middleware' to add validation middleware on mutation's input, I created a sample middleware function that logs the input. export const logInput = async (resolve, root, args, context, ...

disable the button border on native-base

I'm attempting to enclose an icon within a button, like so: <Button style={styles.radioButton} onPress={() => { console.log('hdjwk'); }}> <Icon ...

Implementing dynamic keys in a JSON data structure with Node.js

Specifically focused on utilizing Node.js ES6 capabilities. I am currently working on creating a JSON document for insertion into a MongoDB database. The keys for inserting the document will be derived from the input values provided. For instance, Here i ...

Encountering an issue with Nuxt 3.5.1 during the build process: "ERROR Cannot read properties of undefined (reading 'sys') (x4)"

I am currently working on an application built with Nuxt version 3.5.1. Here is a snippet of the script code: <script lang="ts" setup> import { IProduct } from './types'; const p = defineProps<IProduct>(); < ...

The module.run function in Angular is invoked with each individual unit test

Hey there I am currently working on setting up jasmine-karma unit tests for my angular app. The problem arises in my app.js file where the module.run method is calling a custom service (LoginService) that then makes a call to the $http service. The issue ...

The Clash Between Jquery 2.1.1 and Lightbox

I am trying to incorporate a photo upload feature with a lightbox on a single page, however, I encountered a conflict between my jquery-2.1.1 and lightbox js. I attempted to use jQuery.conflict(); to resolve the issue, but it resulted in another error "jQu ...

Transforming data from a singular object into an array containing multiple objects with key-value pairs

Looking for assistance with converting data from a single object in JSON format to another format. Here is the initial data: var originalData = { "1": "alpha", "2": "beta", "3": "ceta" } The desired format is as follows: var convertedData = ...

Encountering challenges with implementing debouncing functionality in React programming

import React,{useState} from 'react'; const app = () => { const [inputValue, setInputValue] = useState(); const handleChange = (e) => { setInputValue(e.target.value); console.log(inputValue); } const d ...

What is the purpose of enclosing an Angular app within a function?

As I delve into learning Angular, I've encountered a recurring snippet in the app.js file across various resources: (function () { \\\myAngularModules })(); Despite its prevalence, the explanation provided is often just ...

Having trouble with my PHP/AJAX code - the Ajax request to PHP isn't functioning correctly, causing the rows not

I am currently working on a PHP chat application and running into some issues with utilizing AJAX to fetch data from a MySQL database and display it within a designated div. Below are the snippets of my code: HTML <div id="chatbox"> <div cla ...

Troubleshooting CSS override issues when swapping components in ReactJS

Access.js import React from 'react' export default class Access extends React.Component { componentWillMount(){ import ('./styles/access_page.css'); } .... <Link to="/new-account">Sign Up</Link> } Cr ...

Displaying content based on the identified in child route's components

Unique Scenario: In the application, there are different routes configured such as: /feature/1/page1 /feature/1/page2 /feature/2/page1 The /feature route is managed by AppRoutingModule, while the remaining routes are handled by FeaureRoutingModule: co ...

Engaging User Forms for Enhanced Interactivity

I'm in the process of developing an application that involves filling out multiple forms in a sequential chain. Do you have any suggestions for creating a more efficient wizard or form system, aside from using bootstrap modals like I currently am? C ...