Mastering server requests in Angular 5

I have come across recommendations stating that server requests should be made via services and not components in order to ensure reusability of functions by other components. Ultimately, the server response is needed in the component.

My query pertains to the best practice for making a call from the component to the service to retrieve data. I am concerned because HTTP requests are handled asynchronously using Observables.

If I were to do something like this:

//data.component.ts
  const data = this.httpService.getDataFromTheServer();

//httpService.service.ts
  getDataFromTheServer(){
       return this.http.post(url).map(
         res=>res.json())
       }

The data does not populate in the component's variable.

My solution to this issue is using another "Subject" as follows:

 //data.component.ts     
 this.httpService.getDataFromTheServer()
 this.httpService.getData.subscribe(res => {
    const data = res;
}

//httpService.service.ts
   public getData = new Subject();

  getDataFromTheServer(){
       return this.http.post(url).map(
         res=> this.getData.next(res.json()))
       }

While this works fine, I am unsure if it's the best practice. Does anyone have any alternative ideas? Thank you!

UPDATE

Thank you to all who responded. I now understand that in my component, I can use:

this.httpService.getDataFromTheServer().subscribe...

But I am curious if there is a way to streamline my components further and make do with just:

const data = this.httpService.getDataFromTheServer()

Is there another method to simplify the components or did I misunderstand the recommendation to "make server requests via services"? I would appreciate further clarification.

Answer №1

It's important to note that your initial approach may not yield the desired results. This is because the "this.http.post" method does not return request data, but rather an observable object. Therefore, it is necessary to subscribe to the object in order to retrieve the data :)

//data.component.ts
const data = this.httpService.getDataFromTheServer();
data.subscribe(res => console.log(res)); // or assign res to a different variable

//httpService.service.ts
getDataFromTheServer(){
   return this.http.post(url).map(
     res=>res.json())
 }

This approach also allows for easy unsubscription from the Observable.

ngOnDestroy() {
  this.data.unsubscribe();
}

Furthermore, there is no need to bind the service method to a variable. You can streamline it as follows:

//data.component.ts
ngOnInit() {
  this.httpService.getDataFromTheServer()
  .subscribe(res => myVariable = res) // binding response from server to variable
}

//httpService.service.ts
getDataFromTheServer(){
   return this.http.post(url)
   .map(res=>res.json())
 }

// Answer to edit

In theory, you could opt for another approach, but I would recommend utilizing the async pipe to maintain a clean component structure.

Here's how you can do it:

// component.html

<ul>
  <li *ngFor="let item of (items | async)">
</ul>
// or if it's not an array
<h1>{{ item | async }}</h1>

// component.ts

public items;

ngOnInit() {
  this.items = this.httpService.getDataFromTheServer();
}

// service.ts

getDataFromTheServer(){
   return this.http.post(url).pipe(map(res => res.json());
}

Answer №2

Here is a way to achieve this:

//app.component.ts
this.userService.fetchUserData().subscribe((userData) => {
   //process the user data here
});

//user.service.ts
fetchUserData(){
   return this.http.get(userUrl);
}

Remember to subscribe to this.http.get as it returns an Observable<any>.

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

Encountered an issue while trying to establish a connection between node.js and MongoDB

db connection error querySrv ENOTFOUND _mongodb._tcp.nodeapi.vlvom.mongodb.net (node:7720) UnhandledPromiseRejectionWarning: Error: querySrv ENOTFOUND _mongodb._tcp.nodeapi.vlvom.mongodb.net at QueryReqWrap.onresolve [as oncomplete] (dns.js:203:19) (Us ...

Formulate a Generic Type using an Enum

I'm currently working on a project that involves creating a generic Type using enums. Enum export enum OverviewSections { ALL = 'all', SCORE = 'score_breakdown', PERFORMANCE = 'performance_over_time', ENGAGEMENT ...

The Rails application is loading JavaScript three times

I am encountering an issue with my ajax function where it is being triggered multiple times upon click instead of just once. $(document).on('click', '.newGameItem', function() { console.log('start click event'); var a ...

Having trouble with Javascript's JSON.stringify or PHP's json_decode?

I am attempting to send an array from JavaScript to PHP. JavaScript: var json = JSON.stringify(extraFields); url += "&json="+json; PHP: $json = json_decode($_GET['json'], true); foreach($json as $K=>$V){ echo "json".$K . "=" . $V ...

Using Python to interact with forms and click JavaScript buttons

Is there a way to automate form filling on a website by setting specific parameters that will bring up products matching those parameters? I attempted to use mechanize in python, but it does not support javascript. It seems like the process of entering par ...

Switching the border of a div that holds a radio button upon being selected

I have a piece of code that I use to select a radio button when clicking anywhere within a div, which represents a product photo. To make it clear for the customer, I want to add a border around the selected product. Here is the initial code: <script t ...

Leveraging external modules within Angular 2 to enhance component functionality

I have developed a custom module called ObDatePickerModule, which includes a directive. In addition, I have integrated the ObDatePickerModule into a project by including it in the dependencies section of the package.json. Now, I am importing Module A i ...

Issues with javascript functionality in Internet Explorer version 9 and higher

Currently, there is a flash music player (audioplay) embedded on a website. Despite personal preferences against having music on websites, it was requested by the client. The functionality in question involves using JavaScript to trigger "stop" and "play," ...

How can one access the owner function from a different function?

Check out the example on jsfiddle: https://jsfiddle.net/cg33ov4g/3/ (function($){ var foo='foo_value'; var bar='bar_value'; function getVar(theVar){ console.log(this[foo]); console.log(this[bar]); //the c ...

(NodeJS + Socket IO Issue) NodeJS is sending duplicate data when the page is refreshed, causing an improper response

Each time I refresh a page, NodeJS seems to be repetitively writing data on the socket. Interestingly, the number of writes increases with each page refresh but then stabilizes at three after several refreshes. I urge you to inspect the console output whi ...

Loading `.obj` and `.mtl` files in THREE.js with accompanying PNG textures

I am facing an issue while attempting to load an mtl file with reference to png textures for my obj model. The error I am encountering is as follows: TypeError: manager.getHandler is not a function Below is the snippet of my three.js code: var loadOBJ = ...

NextImage's ImageProps is overriding src and alt properties

I've created a wrapper called IllustrationWrapper that I'm utilizing in different components. import Image, { ImageProps } from 'next/image'; const getImageUrl = (illustrationName: string) => { return `https://my-link.com/illustra ...

Showing an error message upon submission in Angular 4 according to the server's response

Struggling for hours to display an error message when a form submits and returns an error status code. The solution seems elusive... In the login form component below, I've indicated where I would like to indicate whether the form is valid or invalid ...

Utilizing jQuery to Sort Table Rows based on an Array of Class Names

I have a table containing values and a filter option where users can select multiple values to filter the table. I want to create a filter with numbers ranging from 1 to 10, and assign class names like filter_1, filter_2, filter_3, etc. to each table row ( ...

What is the process for assigning a function and its arguments as a callback in programming?

Here is a code snippet for your consideration: $scope.delete=function(){ foo('x',3); }; How can we improve the clarity of this code snippet when the callback function contains only one line that calls another function? It's important ...

Tips for avoiding flickering in a background image when it is being changed

Utilizing JavaScript, I am setting a repeated background image from a canvas to a div in the following way: var img_canvas = document.createElement('canvas'); img_canvas.width = 16; img_canvas.height = 16; img_canvas.getContext('2d' ...

What is the most common method for creating a dropdown menu for a website's navigation?

Is there a common approach to creating an interactive drop-down navigation menu in the industry? I have searched on Google and found multiple methods, but as a student working on my first big web project, I am hoping to find a standard practice. I don&apo ...

Tips for enhancing the appearance of a React component

I have a redux form that doesn't look great, and I would like to style it. However, my project uses modular CSS loaders. The styling currently looks like this: import styled from 'styled-components'; const Input = styled.input` color: #4 ...

"Failed to insert or update a child record in the database due to a SQL

I encountered an issue while trying to perform the following transaction: static async save(habit){ await db.beginTransaction; try { await db.execute('SELECT @habitId:=MAX(habits.habitId)+1 FROM habits'); await db.execute( ...

What is the most effective way to reset the v-model in the child component using the parent component?

Could you please assist me? I have been trying for 10 hours straight and it doesn't seem to work. What I am aiming for is that when I click on @click="cleanDataForm" in the Parent Component, the v-model text in the Child component will be emptied. I h ...