ANGULAR JS vs ANGULAR 5 - I want get one specific entry from JSON data and console .log it + my params don’t work

My goal is to give parameters to the webservice and get A specific JSON object but instead of that i am getting the whole JSON ARRAY with a lot of objects.I have some params that i need to set in order to get the specific object.
i have a code file in AngularJS -->

var webapihost = "http://192.168.0.6:81/ebswebapi/";
var scrollerid = "ES00BACKUP/KHCApp_Items"; // For our example, the View (scroller) ID that will be called
var scrid = "ES00BACKUP/KHCApp_Contacts"; 


var commandid = "";                   // For our example, the Automation Command ID that will be called
var mastertableid = "";
var token = "";

/***********  DEMO  ************/

$(document).ready(function () {

    /*
          Call login API
    */
    $.ajax({
        url: webapihost + "api/login",
        type: "POST",
        data: JSON.stringify({
            /*
             Following are the Credentials required to connect to the WebAPI server. Valiable model contains the credensial as they would be entered by an EBS user 
            */
            SubscriptionPassword: 'passx', 
            model: {
                BranchID: "01",
                LangID: "el-GR",
                UserID: "khcadmin",
                Password: "P@ssw0rd"
            }
        }),
        contentType: "application/json; charset=utf-8",
        success: function (result) {

            token = result.Model.WebApiToken;
            document.getElementById("token").innerText = token;

            /*
 After successfull loging in you may process with thw other calls, you have a valid token and you may proceed with other calls.
            */		
			GetScrollerData(token,scrid);
			
        },
        error: function (error) {
            document.getElementById("token").innerText = "error:" + JSON.stringify(error);
            console.log("error:" + JSON.stringify(error));
        }

    });

        function GetScrollerData(token,scrid) {

        /*
            Call to get data from the View (scroller)
        */
        $.ajax({
            url: webapihost + "api/rpc/SimpleScrollerRootTable/" + scrid,
            type: "GET",
            headers: {
                Authorization: 'Bearer ' + token
            },
            data: {       
                Code: "0013168"//Primary Key. If it does't exist it will create new person else it will update the data of the existing objects
				
            },
            contentType: "application/json; charset=utf-8", // returns JSON
            success: function (srcresult) {
                var data = JSON.stringify(srcresult);
                document.getElementById("data").innerText = data;
			

                if (data.length > 0 || typeof data != "undefined") {
               
                }

                
            },
            error: function (error) {
                document.getElementById("data").innerText = "error:" + JSON.stringify(error);
                document.getElementById("data").innerText = "error:" + JSON.stringify(error);
                console.log("error:" + JSON.stringify(error));
            }
        });
    }

});


which works perfect
and i have also this code in Angular 5 which doesn’t work -->

import { HttpClient,HttpEvent,HttpClientModule } from '@angular/common/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import {Observable} from "rxjs/Observable";
import {Storage} from "@ionic/storage";
import {LoginscreenPage} from "../../pages/loginscreen/loginscreen";
import { HttpHeaders } from '@angular/common/http';
import {isSuccess} from "@angular/http/src/http_utils";

var webApihost="http://192.168.0.6:81/EBSWebApi/";
var scrollerid="ES00BACKUP/KHCApp_Items";
var scrid = "ES00BACKUP/KHCApp_Contacts";

@Injectable()
export class LoginserviceProvider {
public token:string;

  params: {
    SubscriptionPassword: string;
    model: {
      BranchID: string;
      LangID: string;
      UserID: string;
      Password: string;
    }
  };

  //scroller code below//

  paramsScroller: {
    headers: {
      Authorization: string;
    },
    data: {
      Code: string;
    }
  };
  //scrid code below//
  paramsScrid: {
    type:string;
    headers: {
      Authorization: string;
    },
    data: {
      Code: string;
    },
    contentType:string;
  };



  url = webApihost + 'api/login';
  url2 = webApihost + "api/rpc/SimpleScrollerRootTable/" + scrollerid;
  url3 = webApihost + "api/rpc/SimpleScrollerRootTable/" + scrid;
type;
  constructor(public http: HttpClient,
              private storage:Storage) {

    console.log('Hello LoginserviceProvider Provider');
    this.url  =webApihost + 'api/login';
    this.url2 =webApihost + "api/rpc/SimpleScrollerRootTable/" + scrollerid;
    this.url3 =webApihost + "api/rpc/SimpleScrollerRootTable/" + scrid;
  }


  getWebApi(url, params) {
    return this.http.post
    (this.url, params);
  }

  getScrollerID(url, paramsScroller){
    return this.http.get
    (this.url2, paramsScroller);
  }
  getScrid(url, paramsScrid ){
    return this.http.get
    (this.url3, paramsScrid);
  }


  authenticationWebApi() {

    this.url = webApihost + 'api/login';
    this.params = {
      SubscriptionPassword: 'passx',
      model: {
        BranchID: "01",
        LangID: "el-GR",
        UserID: "khcadmin",
        Password: "P@ssw0rd"
      }
    };
    console.log("Token Before = " + this.token);
    return this.getWebApi(this.url, this.params)
      .subscribe((data:any) => {
        console.log(JSON.stringify(data));
        this.token = data.Model.WebApiToken;
        console.log(" Token -> " + this.token);
      });

  };


   scrid() {
    console.log("Entered into Scrid");
    this.url = webApihost + "api/rpc/SimpleScrollerRootTable/" + scrid;
    this.paramsScrid = {
      type: "GET",
      headers: {
        Authorization: 'Bearer ' + this.token
      },
      data: {
        Code: "0013168"

      },
      contentType: "application/json; charset=utf-8"
    };
    return this.getScrid(this.url,this.paramsScrid)
      .subscribe((scrid:any) => {
        console.log(JSON.stringify(scrid));
      });
  }
}


How are the requests sent to the server different in both versions?

1 Like

???what do you mean i dont understand the question

You say “it doesn’t work” which I assume means that the requests your code is sending are different and so doesn’t get you the results you want. Or not?

yes. In the first one (with AJAX and Angular .JS) i get the specific JSON object that i want from the server with Setting this param ->

 data: {
        Code: "0013168"

But in the second one(Angular5) i get the whole JSON array and my parameter " Code" is not talking with the server…

This would be the problem here. scrid will refer to the function itself. So it’s not properly calling your API.

1 Like

Your first example is not AngularJS, it’s jQuery, there is zero Angular code there.

Your second example you never call the scrid function, which is probably your issue, but you have a few more. Most importantly creating global variables outside your class definition.

2 Likes

really?? i didint knew that ! Thanks a lot for the feedback.
Also scrid() function is being called in another page.

ionViewWillLoad(){

    setTimeout(()=>{
      return this.loginserviceprovider.scrid()},3000);

    }

so i change the name of the function?

I’d imagine that your scrid function is supposed to accept an argument, no?
So something like

scrid(id: string) {
this.url = this.url = webApihost + "api/rpc/SimpleScrollerRootTable/" + id;

(I’m not sure what “scrid” is supposed to represent in the URL. so I’m just assuming it’s an id)

Ummm, why are you waiting three seconds after page load then calling that?

You may want to go back and review Promises and Observables, and async programming, and just how to use Angular in general

2 Likes

This is a twisted maze of naming and scoping conflicts.

Do not name methods and properties the same thing. There is only one object namespace in JavaScript, so they will collide.

Do not put the same data in two different scopes. If the parameters to these calls change on every invocation (as is typical), get rid of all the params* object properties and declare them as method arguments.

Variable and method names are important. They convey meaning to a reader. url1, url2, url3 are meaningless. They are also declared both at file and object scope, which makes no sense. Pick one.

Inline types are hard to read. Abstract them out into interfaces with meaningful names.

Constructor parameters of a service should always be private, to protect encapsulation.

paramsScrid looks like it is attempting to reinvent HttpClient. Don’t do that. Work with HttpClient and simply call its get and post methods.

In summary, I would completely start over here, using something like the Tour of Heroes service chapter as a model and keeping the above guidelines in mind.

2 Likes

i re-wrote my code, more cleaner now both the provider and the home page…
i took into consideration our comments and suggestions but my problem still exists
i get the Whole JSON objects and Not the specific parts that i want =/

My service file

import {HttpClient, HttpEvent} from '@angular/common/http';
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';

@Injectable()
export class LoginserviceProvider {
 
  constructor(private http: HttpClient) {
  }
  getWebApi(url, params) {
    return this.http.post
    (url, params);
  }
  getScrid(url, params ){
    return this.http.get
    (url, params);
  }
}

My home page

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import {LoginserviceProvider} from "../../providers/loginservice/loginservice";

let webApihost="http://192.168.0.6:81/EBSWebApi/";
let scrid = "ES00BACKUP/KHCApp_Contacts";
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  public token:string;
  url = webApihost + 'api/login';
  url3 = webApihost + "api/rpc/SimpleScrollerRootTable/" + scrid;

  constructor(private navCtrl: NavController,
              private loginservice:LoginserviceProvider) {
  }

  ionViewWillEnter(){
    setTimeout(()=>{
      this.authenticationWebApi();
    },3000);
    setTimeout(()=>{
      return this.callScrid()},10000);
  }

  authenticationWebApi() {
    this.url = webApihost + 'api/login';
    let params = {
      SubscriptionPassword: 'passx',
      model: {
        BranchID: "01",
        LangID: "el-GR",
        UserID: "khcadmin",
        Password: "P@ssw0rd"
      }
    };
    
    return this.loginservice.getWebApi(this.url, params)
      .subscribe((data:any) => {
        console.log(JSON.stringify(data));
        this.token = data.Model.WebApiToken;
      });
  };

  callScrid() {
    let paramsScrid = {
      type: "GET",
      headers: {
        Authorization: 'Bearer ' + this.token
      },
       data: {
         Code: "0013168"
       },
       contentType: "application/json; charset=utf-8"
      };
    return this.loginservice.getScrid(this.url3,paramsScrid)
      .subscribe((scrid:any) => {
        console.log(JSON.stringify(scrid));
      });
     }
}

this param →

data: {
         Code: "0013168" 
}

has to choose the specific Json object that i want to get with 0013168 code …as the above Jquery file does but it does not.

Your use of setTimeout looks dangerous to me. Use a Promise, or some other way to listen for an ack.

it is …but it’s not the case of my current problem right now…
I will fix it though in the near future, because i don’t know how to play with promises at this moment.
I used Observables at the scratch of my app but it seemed useless .

As currently written, your provider is pointless. I would start over with the following skeleton:

export class TokenService {
  private _tokens = new BehaviorSubject<string>(undefined);

  constructor(private _storage: Storage) {
    this._storage.get('authtoken')
      .then(token => this._token.next(token));
  }

  token(): Observable<string> { 
    return this._token.asObservable(); 
  }

  setToken(string token): void {
    this._storage.set('authtoken', token).then(() => {
      this._token.next(token);
    });
  }
}

export class AuthedHttp implements HttpInterceptor {
  constructor(private _tokens: TokenService) {}
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    return this._tokens.token()
      .pipe(
        first(),
        mergeMap((jwt) => {
          let areq = req.clone({setHeaders: {Authorization: 'Bearer ' + jwt}});
          return next.handle(areq);
        }));
  }
}

export interface Credentials { /* tbd */ }
export interface WhateverTheHellAScridIs { /* tbd */ }

export class MothershipService {
  constructor(private _tokens: TokenService, private _http: HttpClient) {}
  login(creds: Credentials): Observable<string> {
    return this._http.post(/*url*/, creds).pipe(
      tap(jwt => this._tokens.setToken(jwt)));
  }
  scrid(code: string): Observable<WhateverTheHellAScridIs> {
    return this._http.get<WhateverTheHellAScridIs>(/*url*/);
  } 
}

export class HomePage {
  scrid = {} as WhateverTheHellAScridIs;
  code: string;
  creds = {} as Credentials;
  constructor(private _mama: MothershipService) {}
  login(): void {
    this._mama.login(this.creds).subscribe(() => this._refreshScrid());
  }

  private _refreshScrid(): void {
    this._mama.scrid(this.code).subscribe(scrid => this.scrid = scrid);
  }
}

The page must think of the MothershipService as something that magically gives it exactly what it wants, when passed whatever is minimally necessary to get it. It knows nothing whatsoever of how that process works. The MothershipService knows that it has to tell the TokenService whenever it performs a successful login() beyond that it has no care in the world about authentication details. All that is taken care of by AuthedHttp, which only cares that TokenService will feed it tokens. TokenService is a veneer over Storage that allows tokens to be persisted across app restarts. It is oblivious to how they are used.

Everybody has a defined role, and the delineation of responsibility is sharply drawn.

Thanks for the Feedback, it helps me a lot as i am newbie
i have some questions though
1.All these classes i will run them in different files right?
2.Also i am getting an error like that in AuthedHttp class


why?

  1. finally
    here inside the interfaces with the comment “tdb” which means the database?? i will write the urls?
export interface Credentials { /* tbd */ }
export interface WhateverTheHellAScridIs { /* tbd */ }

Thanks a lot in advance

Right.

I would love to quote said error, but you posted an image and not text as text. Probably something with your Angular version or how you are importing operators.

That means “to be determined”. You have to write the contents of those interfaces. I don’t know what goes in them.

1 Like