reiniX86
reiniX86

Reputation: 199

Angular http request not working correctly

Angular makes me crazy.

I have two buttons. If I click on the first one, I want to make this request:

https://localhost:44373/api/events

If I click on the second one, I want to make that request:

https://localhost:44373/api/events/1

The method "getNextPost()" will be called and it seems to work, but on Server side the addressed Methods will not be called.

Here is my client implementation:

 export class AppComponent implements OnInit {
  title = 'EventsPresenter';
  _hubconnection : signalR.HubConnection;

  _notification : string = '';

  displayedColumns: string[] = ['eventDateTime', 'nbr', 'element', 'parent', 'stateTypeTitle', 'enumValueTitle', 'customerObject'];

  ROOT_URL = 'https://localhost:44373/';
  ROOT_API_URL = this.ROOT_URL + 'api/';
  dataSource: Observable<EventData[]>;
  dataSource2: Observable<EventData>;

  constructor(private http: HttpClient) {}

  getPosts(){
    this.dataSource = this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
  }

  getNextPost(){
    this.dataSource2 = this.http.get<EventData>(this.ROOT_API_URL + 'events/1')
  }


  ngOnInit() {

    this._hubconnection = new signalR.HubConnectionBuilder() 
    .configureLogging(signalR.LogLevel.Trace) 
    .withUrl('https://localhost:44373/notify') 
   .build(); 

    this._hubconnection
      .start()
      .then(() => console.log('Connection Started'))
      .catch(err => console.log('Error while establishing connection'));

      this._hubconnection.on('BroadcastMessage', (data: EventData) => {    
        console.log(data);
        this.dataSource.subscribe(v => v.push(data));
      });

  }
}

Here is my server implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using convisAPI.DataProvider;
using convisAPI.Interfaces;
using EntityLibrary;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;

namespace convisAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EventsController : ControllerBase
    {
        //EventDataProvider eventDataProvider;

        IEventDataRepository _eventDataRepository;

        IHubContext<NotifyHub> _hubContext;

        public EventsController(IEventDataRepository eventDataRepository, IHubContext<NotifyHub> hubContext)
        {
            _eventDataRepository = eventDataRepository;
            _hubContext = hubContext; 
        }

        // GET api/events
        [HttpGet]
        public async Task<ActionResult<IEnumerable<EventSummary>>> Get()
        {
            return await _eventDataRepository.GetEvents();
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public async Task<ActionResult<EventSummary>> Get(int id)
        {

            Random r = new Random();

            var ra = r.Next(212, 220);

            await _hubContext.Clients.All.SendAsync("BroadcastMessage", new EventSummary()
            {
                Element = "Mein Element " + ra,
                Details = "Das ist mein Eventgrund",
                EventID = Guid.NewGuid(),
                ElementID = Guid.NewGuid(),
                EventDateTime = DateTime.Now,
                Nbr = ra,
                StateNbr = ra,
                EnumValueTitle = "Störung",
                StateEnumValue = 110 + ra
            });


            return new EventSummary();



        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

I know that the code "Get(int id)" may look strange for you, but I basically want to trigger an SignalR Notification.

Any ideas?

best regards

Upvotes: 2

Views: 6597

Answers (3)

Omar
Omar

Reputation: 1040

For those landing here that don't have any of the issues mentioned, it's worth checking your interceptors, if you have any.

Upvotes: 2

JanRecker
JanRecker

Reputation: 1847

in Angular, each HTTP request will only "fire" when someone listen´s to them.

So, if there is no one who subscribe´s, than there won´t be any http-request.

getPosts(){
    this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
         .subscribe(result => this.dataSource = result)
}

getNextPost(){
    this.http.get<`EventData>(this.ROOT_API_URL + 'events/1')
        .subscribe(result => this.dataSource2 = result)
}

I would write it a bit different, but thats personal style Instead of

getPosts(){
   this.dataSource = this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
 }

i would write

getPosts():Observable<EventData[]>{
   return this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
}

and then i would subscribe at the point where i need the data.

...
this.getPosts().subscribe(result => this.isWhereINeedit = result)

warm regards

Upvotes: 6

Shadab Faiz
Shadab Faiz

Reputation: 2508

There 2 issues here.

1st: HttpClient.get() method returns an Observable. Observable does not get triggered/fired unless they are subscribed. For Ex:

/* This wont work because it is not subscribed. */
someMethod() {
http.get(someUrl);
}

// this is work since it is subscribed.
someMethod() {
http.get(someUrl).subscribe(res => console.log(res));
}

So in your case, the call to server is not being made. Check in browser's network. If the call is made, then it should show there.

2nd: CORS ISSUE. Since the origin of Request to the server and Response from Server are different, you might be having cors issue. During the development phase, you can use a browser plugin to work around that, but it will still occure during the production (when you go live). To properly resolve it, some change needs to be made on the server side. Add these on your server:

  // Website you wish to allow to connect
    res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');

    // Request methods you wish to allow
    res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');

    // Request headers you wish to allow
    res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');

    // Set to true if you need the website to include cookies in the requests sent
    // to the API (e.g. in case you use sessions)
    res.setHeader('Access-Control-Allow-Credentials', true);

Upvotes: 1

Related Questions