Problem with sequential promises

import { Observable } from 'rxjs/internal/Observable';

export function createHttpObservable(url: string) {
    console.log('Url is', url);
    return Observable.create(observer => {
        fetch(url)
        .then(response => {
            console.log(response);
            console.log(response.json());
            return response.json();
        })
        .then(body => {
            observer.next(body);
            observer.complete();
        })
        .catch(err => observer.error(err));
    });
}

I am encountering an issue with the above code where the execution does not progress to the second then block. The browser console logs are shown below.

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

Interestingly, if I eliminate the line console.log(response.json());, the code functions correctly. This appears to be a basic question, but I am unable to identify the cause. Any assistance would be greatly appreciated. Thank you in advance.

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

Answer №1

The Response#body is actually a unique type of stream known as a ReadableStream. Once this stream is consumed, it becomes empty and cannot be used again. When the Body#json() method completely reads the stream, any subsequent attempt to access the same body results in tapping into an already empty stream. This behavior is intentional in the Response API implementation to avoid calling the method twice.

You can experiment with this yourself:

const a = new ReadableStream();
const b = new Response(a);

b.json(); // returns a Promise
b.json(); // TypeError: Failed to execute 'json' on 'Response': body stream is locked

Answer №2

When you use response.json(), the resource becomes locked, causing the second call to fail.

It's best to only make the call once, but if you really need to see the result, here is a code snippet that may help:

   Add this part
       \/
.then(async response => {
    console.log(response);
    console.log(await response.clone().json()); // retrieve json result from cloned response
    return response.json();
})

Alternatively, you can simply log it in the second then:

.then(async response => {
   console.log(response);
   return response.json();
 })
.then(body => { 
   console.log(body); // no workaround needed
   observer.next(body);
   observer.complete();
})

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

Changes are reflected in the service variable, but they are not updating in the component

I am facing an issue with a variable that is supposed to track the progress of image uploads. The variable seems to be working fine, but it remains undefined in my component. Upload Service method uploadProfilePic(url:string, user_id:string, image:any) { ...

Updating a list item in AngularFire2 triggers a change in the overall list

I have successfully implemented an update call to Firebase, but I am experiencing an issue where the list on which I am looping is being refreshed, causing my input field to lose focus. Is there a way for me to trigger the update without refreshing the or ...

"Send the selected radio button options chosen by the user, with the values specified in a JSON format

My current task involves inserting radio button values into a MySql database using Angular. The form consists of radio buttons with predefined values stored in a json file. Below is an example of how the json file is structured: //data.json [{ "surve ...

Chunk loading in IE 11 has encountered an error

Having an issue with my website which is created using Angular 5. It seems to be malfunctioning in IE 11, and I am encountering the following error in the console: https://i.stack.imgur.com/Ek895.png Any insights on why my Angular code isn't functio ...

Utilizing Sequelize with Typescript for referential integrity constraints

After defining these two Sequelize models: export class Users extends Model<Users> { @HasMany(() => UserRoles) @Column({ primaryKey: true, allowNull: false, unique: true }) UserId: string; @Column({ allowNull: false, unique: tru ...

The term 'shuterstock_init' is meant to be a type, however, it is mistakenly being treated as a value in this context

I am working on a service called class imageService, which mainly consists of key value pairs export type servicesName = "unsplash" | "pexels" | "pixabay" | 'shutterstock'; export type Service = { [key in services ...

Angular ngModel failing to accurately reflect changes in input value

I am facing an issue with implementing a smart number input component that can toggle between allowing or disallowing negative numbers. I have an event listener for the (input) on the <input> element, triggering a function that applies various regex ...

Unable to retrieve the key value from a child object in Angular 2 when working with JSON Data

Currently, I am using Angular and attempting to extract data from the child object's key value. Here is the JSON data provided: "other_lessons": [ { "id": 290, "name": "Christmas Test #290", "course": { "id": ...

Obtaining data attributes in Angular 8

I'm working with Angular 8 and I came across an issue. In my code snippet, there are two data attributes assigned to a button element, but only one attribute is showing up. Is this a syntax error or a bug? <button [attr.data-popolamento]="all" [a ...

The error message "The file 'environment.ts' is not located within the specified 'rootDir' directory" was encountered during the Angular Library build process

When attempting to access the environment variable in an Angular 9 library, I encountered an error during the library build process. Here is how it was implemented: import { EnvironmentViewModel } from 'projects/falcon-core/src/lib/view-models/envir ...

Modifying the return type of an observable using the map operator

I have been investigating how to modify the return type of an Observable. My current framework is Angular 5. Let's take a look at this example: public fetchButterflyData(): Observable<Butterfly[]> { return http.get<Larva[]>('u ...

Customizing the default font color in Angular Material

I am currently navigating through theming in Angular Material and feeling a bit disoriented. I have implemented the prebuilt indigo-pink theme by importing it into my styles.scss as shown below: @import "~@angular/material/prebuilt-themes/indigo-pink.css" ...

Encountering an issue: a function is required to return a value if its declared type is not 'undefined', 'void', or 'any'

I have a specific function type that is capable of returning either void or Promise<void: export type CommandHandler = (values: CommandValues) => void | Promise<void>; Currently, I am attempting to utilize this function type in a void function ...

Issues with the daterange filter in Angular SlickGrid causing functionality problems

Within Angular SlickGrid, I have implemented two date columns where the values are derived from a specific class. These columns correspond to two date fields within this class. My intention is to represent these values in dateTimeShortIso format and apply ...

Angular 6 form input value displays incorrectly after dynamically closing a tab

After adding a child-component with a form inside a tab, I noticed that when I closed the tab, the child-component form value was changed to the deleted tab. However, the span value remained correct. It's quite strange - could this be a bug? Check ou ...

Components for managing Create, Read, Update, and Delete operations

As I embark on my Angular 2 journey with TypeScript, I am exploring the most efficient way to structure my application. Consider a scenario where I need to perform CRUD operations on a product. Should I create a separate component for each operation, such ...

The specified module '...' is identified as a non-module entity and therefore cannot be imported using this specific construct

Currently, I am facing an issue in my .tsx file where I am attempting to import a RaisedButton component from material-ui using the following code: import * as RaisedButton from 'material-ui/lib/raised-button' Unfortunately, this is triggering ...

Steps to activate a button once the input field has been completed

https://i.sstatic.net/l6mUu.png It's noticeable that the send offer button is currently disabled, I am looking to enable it only when both input fields are filled. Below, I have shared my code base with you. Please review the code and make necessar ...

Assigning a value to an angular object

In my current project with Angular 16, I am executing a query on the database and assigning the returned number to a document number. Data Model export class Document { doc_data: string =""; doc_for: string=""; doc_number: number = 0; doc_ ...

Error in Typescript: Function not being triggered on button click

As someone who is just starting out with typescript, I've been tackling a simple code that should display an alert message in the browser when a button is clicked. I've experimented with the button and input tags, as well as using both onclick ev ...