Spring Boot + NativeScript [ Connection ]


#1

I installed a server on Spring Boot, a very simple server that is running perfectly on my localhost.
Since its running on my localHost, there shouldnt’ be any connection refused problems since there is no need for a proxy.
I am 100% positive that my server is running . I think at least.
Proof:
Class: UserController.java


package fastcanteen;

import java.util.concurrent.atomic.AtomicLong;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {


    @RequestMapping("/")
    public User user(User user) {
        System.out.println(user.toString());
        return user;
    }

}

My class user.java

package fastcanteen;

public class User {

    private int nif;
    private String password;

    public User(){
    }
    public User(int nif, String password) {
        this.nif = nif;
        this.password = password;
    }

    public long getNif() {
        return nif;
    }

    public String getPassword() {
        return password;
    }
}

Main class

package fastcanteen;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Deploying the server:

As you can see the Server is working.

Now my application on NativeScript [Currently using TypeScript + Angular 2.0]

class: user.service.ts

import { Injectable } from "@angular/core";
import { Http, Headers, Response } from "@angular/http";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/do";
import "rxjs/add/operator/map";

import { User } from "./user";
import { Config } from "../config";

@Injectable()
export class UserService {
  constructor(private http: Http) { }

  register(user: User) {
    let headers = new Headers();
    headers.append("Content-Type", "application/json");

    return this.http.post(
      Config.apiUrl + "Users",
      JSON.stringify({
        Username: user.nif,
        Email: user.nif,
        Password: user.password
      }),
      { headers: headers }
    )
      .catch(this.handleErrors);
  }

  login(user: User) {
    let headers = new Headers();
    headers.append("Content-Type", "application/json");

    console.log("inside login user.service.ts");
    console.log(user);
    console.log(Config.apiUrl);
    console.log(user.nif);
    console.log(user.password);
    return this.http.post(
      Config.apiUrl ,
      JSON.stringify({
        nif: user.nif,
        password: user.password,
        //grant_type: "password"
      }),
      { headers: headers }
    )
      .map(response => response.json())
      .do(data => {
        Config.token = data.Result.access_token;
      })
      .catch(this.handleErrors);
  }

  handleErrors(error: Response) {
    console.log(JSON.stringify(error.json()));
    return Observable.throw(error);
  }
}

My class user.ts

export class User {
  nif: number;
  password: string;

  constructor() {
  }

  set newNIF(newNIF: number) {
    this.nif = newNIF;
  }

  set newPassword(newPassword: string) {
    this.password = newPassword;
  }
}

My class : app.module.ts

import { NgModule } from "@angular/core";
import { NativeScriptFormsModule } from "nativescript-angular/forms";
import { NativeScriptHttpModule } from "nativescript-angular/http";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { NativeScriptRouterModule } from "nativescript-angular/router";

import { AppComponent } from "./app.component";
import { routes, navigatableComponents } from "./app.routing";
import { UserService} from "./shared/user/user.service";

@NgModule({
  imports: [
    NativeScriptModule,
    NativeScriptFormsModule,
    NativeScriptHttpModule,
    NativeScriptRouterModule,
    NativeScriptRouterModule.forRoot(routes)
  ],
  declarations: [
    AppComponent,
    ...navigatableComponents
  ],
  providers: [UserService],
  bootstrap: [AppComponent]
})
export class AppModule {}

I am getting the following error:

I have no clue why he is saying connection refused…
When i was following the tutorial on Groceries application as soon as i clicked the login button it actually didnt let me login. Basically the connection to the API provided on the tutorial wasn’t working for me.

Anyone has any idea on how to fix this?
@NathanaelA @jen.looper @Eddy @bradwaynemartin @tjvantoll


#2

Actually you need to go into a browser on the mobile phone and attempt to go to the URL you think it is and verify the device can see the server.

Localhost from the server only tells us the server is setup on its private localhost interface. You need to verify the server is actually working from an external ip address; so using the phone’s browser is the best test to make sure your server it is externally visible.

Nathanael A.


#3

You need to verify the server is actually working from an external ip address; so using the phone’s browser is the best test to make sure your server it is externally visible.

What do you mean by this? should i try to acess it from my own cellphone or from my own created emulator?

I tried from my owncellphone and i didn’t achieve any results. It says it can’t find the server.

I posted the url on the postman it seems to be working.

Really need help on this… if you could @NathanaelA


#4

I had the same issue before. The problem is when you connect to localhost:8080 from your computer, it works because the server, spring boot, is running, and it knows what is your localhost. For example if you have 2 computers on the same network and you navigate to localhost on each of them, you will get different results. To fix your issue, set spring boot server ip to your local ip. If you are on linux/mac, open your terminal and type “ifconfig”. Then get the ip of your computer and use it in spring boot. Then with your phone, connect to the same network and it will be able to see your server. Also, you could use a public ip on your server or use Heroku and then you’ll be able to connect to your server.

Just keep in mind that localhost is different on each device even if they are in the same network.


#5

@PurpleRune as @aebe has said; localhost is ALWAYS pointed to the local computer. So if you type localhost on Computer A, it will point to Computer A, if you type localhost on computer B it will point to computer B. When you type localhost on your Cell phone, it points to the cell phone.

For your cell phone (or another computer) to talk to a page running on Computer A; you need to connect to it via an external IP address. (ifconfig or ipconfig depending on the operating system) will give you a list of ip addresses that are setup on the computer. So when I run this on the http://nativescript.rocks server I see:

“Lo” = “Local” = “Loopback” = “127.0.0.1”
“p1p1” interface is one of the ip addresses that the machine uses for external connection and you can see its internet address is 206.190.130.28. So when you type http://nativescript.rocks it goes to that address for you to see all the sites I have hosted on one of my servers.

Does this help explain it a little bit. You need the ip address that is external to your machine for your cell phone to connect to it.

Nathanael A.


#6

@NathanaelA @Aebe

The solution you guys provided worked althought i can’t still achieve the login result i pretend. This is almost exactly like the Groceries tutorial since i also get stuck in the login() part at Groceries.

To be more precise i get exaclty stuck on the section 3.5 of Groceries Tutorial on Nativescript using TypeScript + Angular 2.0
I can never finish the Login part. it always generates this alert.

And the Post Http request am using is really simple:

class: user.service.ts[ User Service]

import { Injectable } from "@angular/core";
import { Http, Headers, Response } from "@angular/http";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/do";
import "rxjs/add/operator/map";

import { User } from "./user";
import { Config } from "../../config";

@Injectable()
export class UserService {
  constructor(private http: Http) { }

  register(user: User) {
    let headers = new Headers();
    headers.append("Content-Type", "application/json");

    return this.http.post(
      Config.apiUrl + "Users",
      JSON.stringify({
        Username: user.nif,
        Email: user.nif,
        Password: user.password
      }),
      { headers: headers }
    )
      .catch(this.handleErrors);
  }

  login(user: User) {
    let headers = new Headers();
    headers.append("Content-Type", "application/json");

    console.log("inside login user.service.ts");
    console.log(user);
    console.log(Config.apiUrl);
    console.log(user.nif);
    console.log(user.password);
    return this.http.post(
      Config.apiUrl ,
      JSON.stringify({
        nif: user.nif,
        password: user.password,
        //grant_type: "password"
      }),
      { headers: headers }
    )
      .map(response => response.json())
      .do(data => {
        Config.token = data.Result.access_token;
      })
      .catch(this.handleErrors);
  }

  handleErrors(error: Response) {
    console.log(JSON.stringify(error.json()));
    return Observable.throw(error);
  }
}

class user.ts [ Model class user]

export class User {
  name: string;
  nif: number;
  password: string;

  constructor(){
    
  }


  set newName(newName: string) {
    this.name = newName;
  }

  set newNIF(newNIF: number) {
    this.nif = newNIF;
  }

  set newPassword(newPassword: string) {
    this.password = newPassword;
  }
}

class login.component.ts [ User Interface]

import { Page } from "ui/page";
import { User } from "../../shared/model/user/user";
import { UserService } from "../../shared/model/user/user.service";
import { Component, OnInit } from "@angular/core";
import { Router, NavigationExtras } from "@angular/router";

@Component({
  selector: "my-app",
  providers: [UserService],
  templateUrl: "pages/login/login.html",
  styleUrls: ["pages/login/login-common.css", "pages/login/login.css"],
})

export class LoginComponent implements OnInit {
  public user: User;
  isLoggingIn = true;

  
  constructor(private router: Router, private userService: UserService, private page: Page) {
    this.user = new User();
    this.user.name = "João Soares";
    this.user.nif = 500000379;
    this.user.password = "Password";
  }

  submit() {
    if (this.isLoggingIn) {
      this.login();
    } else {
      this.signUp();
    }
  }
  login() {

    // This code is used to make the connection to the Angular Services
    console.log("user dentro do metodo login , classe login.component.ts");
    console.log(this.user);
    console.log("Estou aqui");
    console.log(this)
    this.userService.login(this.user).subscribe(
      () => this.router.navigate(["/homePage"]),
      (error) => alert("Unfortunately we could not find your account.")
      );


    //this.router.navigate(["/transactions"]);
    console.log("Login Button Clicked!");
    let navigationExtras: NavigationExtras = {
      queryParams: {
        "user": JSON.stringify({
          "name":this.user.name,
          "nif": this.user.nif,
          "password": this.user.password
        })
      }
    };
    this.router.navigate(["/homePage"], navigationExtras);
  }

  signUp() {

  }
  toggleDisplay() {
    this.isLoggingIn = !this.isLoggingIn;
  }
  register() {
    console.log("Register here free Button clicked!");
    this.router.navigate(["/register"]);
  }
  ngOnInit() {
    this.page.actionBarHidden = true;
    this.page.backgroundImage = "res://bitmap";
  }
}


I dont get why he triggers this code

      (error) => alert("Unfortunately we could not find your account.")
      );

Do you guys have any idea?
Thank you in advance!


#7

If this is the grocery demo; then you need to talk to @tjvantoll.

Nathanael A.


#8

Hi @PurpleRune,

Sorry that you’re hitting issues here. I went through the tutorial again this morning and didn’t hit any issues, so I’m not sure what’s up here. There’s a bit of code in the user service that logs errors to the console (see https://github.com/NativeScript/sample-Groceries/blob/9c6771486362e91e4991f126fa45f58d1db66376/app/shared/user/user.service.ts#L51). Could you share what you’re seeing in your console when you’re having these login problems?

Thanks,
TJ


#9

I managed to resolve this issue. I connected a physical device on the same network as my computer, solving therefore the problem of this connection.

Since the android emulator i was using doesn’t have wifi,
well actually, no android emulator has connection to wi-fi i think, i had to connect on a real physic device in order to be able to make this connection work.
Thanks
@NathanaelA
@tjvantoll
@Aebe


#10

Nah, you can use wifi; I do it all the time. Emulator’s network connection will act like wifi; you just have to have everything setup correctly. I use emulators against servers quite frequently.

Nathanael A.