'How to get IP address on page load in Angular 4

I'm working in an Angular4 project,In this I'm Trying to get system IP address on page load and pass it to the API for storing the IP address in MSSQL database .Two rows get inserted on each page load and the IP address in showing as "undefined",help me to solve this .

This is my app.component.ts code

import {Component, OnInit} from '@angular/core';
import { HttpClient } from '@angular/common/http';



@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit{   
  publicIP;
  res;
  constructor(private http: HttpClient) {}
  ngOnInit() : void
  {
    this.getip();
    this.http.get("http://localhost:57036/api/data/GetClientIp/?
    IP_Address="+this.publicIP).subscribe(data=>{
    this.res=data as string[]});
  }

getip()
{
  this.http.get('http://freegeoip.net/json/?callback').subscribe(data => {
  this.publicIP=data['ip'];});
}

}

I got the IP address in data but while assigning the value to PublicIP it is showing as "Undefined"

this.http.get('http://freegeoip.net/json/?callback').subscribe(data => {
this.publicIP=data['ip'];});


Solution 1:[1]

Your problem is that you have two concurrent dependent asynchronous calls.

You need the IP from freegeoip before you can save it. So reverse your logic, and make use of the oncomplete callback from an Observable subscription.

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
    publicIP: string;
    res: string;

    constructor(private http: HttpClient) {}

    ngOnInit() {
        this.http.get('http://freegeoip.net/json/?callback')
                 .subscribe(
                    data => this.publicIP = data['ip'], // Data from REST
                    error => console.error(error),      // Error callback
                    () => this.saveIP()                 // Once this call completes
                 );
    }

     saveIP() {
        this.http.get(`http://localhost:57036/api/data/GetClientIp/?IP_Address=${this.publicIP}`)
                 .subscribe(data => this.res = data);
    }
}

But you don't need to save all this state, you can do it functionally, using only the onnext callback:

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.css']
})

export class AppComponent implements OnInit {
    constructor(private http: HttpClient) {}

    ngOnInit() {
        this.http.get('http://freegeoip.net/json/?callback')
                 .subscribe(
                    data => this.saveIP(data['ip']),
                    error => console.error(error)
                 );
    }

     saveIP(address: string) {
        this.http.get(`http://localhost:57036/api/data/GetClientIp/?IP_Address=${address}`)
                 .subscribe(data => this.res = data);
    }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 msanford