Search code examples
angulardataservice

Angular 5: Saving input value from component into service


I am trying to save an input value from a component into my data service, such as input with user name, and input with password, on click it does a post call form the service, but the actual input lives in a separate component where the data service is imported.

how can I bind the data from the input, to add it to a variable in the data service?

UPDATE: I managed to translate the data between DataService and my component. Below is the code.

UPDATE v2: I am now getting a new error "Request header field Content-Type is not allowed by Access-Control-Allow-Headers in preflight response." trying to resolve this.

UPDATE v3: I managed to get everything working, check for the answer below!

DataService:

import { HttpClient, HttpRequest } from '@angular/common/http';

import { Injectable } from '@angular/core';

@Injectable()
export class DataService {
    username:string = '';
    password:string = '';

    convioURL:string;
    loginMethod:string;

    constructor(private http: HttpClient) {}

    getData() {
        this.convioURL = 'https://testurl.com/';
        this.loginMethod = '?testMethod&user_name='+ this.username +'&password='+ this.password +'&response_format=json';
        const req = new HttpRequest('POST', this.convioURL + this.loginMethod, {
            reportProgress: true
        });

        return this.http.request(req);
    }
    usernameKey(value: string) {
        this.username + value;
    }
    passwordKey(value: string) {
        this.password + value;
    }
}

Component:

import { Component, OnInit } from '@angular/core';
import { HttpEvent, HttpEventType } from '@angular/common/http';
import { DataService } from '../data.service';
import * as $ from 'jquery';

@Component({
  selector: 'app-step-01',
  templateUrl: './step-01.component.html',
  styleUrls: ['./step-01.component.scss']
})
export class Step01Component implements OnInit {

    data: any;
    usernameInput: any;
    passwordInput: any;
    constructor(private dataService: DataService) {
    }

    ngOnInit() {
    }

    usernameKey(event: any) {
       this.dataService.username = event.target.value;
    }
    passwordKey(event: any) {
       this.dataService.password = event.target.value;
    }

    private getLoggedIn() {
        this.dataService.getData().subscribe((event: HttpEvent<any>) => {
            switch (event.type) {
                case HttpEventType.Sent:
                    console.log('Request sent!');
                break;
                case HttpEventType.ResponseHeader:
                    console.log('Response header received!');
                break;
                case HttpEventType.DownloadProgress:
                    const kbLoaded = Math.round(event.loaded / 1024);
                    console.log(`Download in progress! ${kbLoaded}Kb loaded`);
                break;
                case HttpEventType.Response:
                    console.log('😺 Done!', event.body);
                    this.data = event.body;
                    console.log(this.data);
          }
        });
    }

}

This is my jQuery code that WORKS perfectly fine, but I am trying to stay away from using jQuery on this app, I want to be able to write this the angular5/typescript way. Hope this helps everyone understand what I am trying to do.

$("#ssoForm").submit(function(e) {
            e.preventDefault();
            var username = $('#username').val();
            var password = $('#password').val();

            var apiURL = 'http://testurl.com/?';
            var loginMethod = 'testMethod&user_name='+ username +'&password='+ password +'&response_format=json';


            $.post(apiURL + loginMethod, 
                function(data) {
                    if (data) {
                        var json = $.parseJSON(data)
                        console.log(json);

                        var consID = json.loginResponse.cons_id;

                        var ssoUser = 'fakeusername';
                        var ssoPassword = 'fakepassword';

                        var ssoMethod = 'fakeSSOMethod&response_format=json&login_name='+ ssoUser +'&login_password='+ ssoPassword + '&cons_id='+ consID;

                        $.post(apiURL + ssoMethod, function(ssoData) {
                            var res = $.parseJSON(ssoData);
                            console.log(res);
                        });
                    } else {
                        console.log('No Data!');
                    }
            });
        });

Component Template:

<form id="ssoForm">
    <table>
        <tr>
            <td>User Name:</td>
            <td><input id="username" name=user_name type=text size=15 maxlength="100" #box (keyup)="usernameKey($event)"></td>
        </tr>
            <tr>
            <td>Password:</td>
            <td><input id="password" name=password type=password size=15 maxlength="100" #box2 (keyup)="passwordKey($event)"></td>
        </tr>
        <tr>
            <td>Remember Me:</td>
            <td><input name=remember_me type=checkbox></td>
        </tr>
    </table>
    <input (click)="getLoggedIn()" type="submit"/>
</form>

Solution

  • I fixed my latest problem by setting up a new function in the data service which is then called in the component I am using.

    In the DataService added the following:

    logMeIn() {
        this.convioURL = 'https://www.testurl.com/';
        this.loginMethod = '?testMethod&user_name='+ this.username +'&password='+ this.password +'&response_format=json';
        this.http.post(this.convioURL + this.loginMethod, null)
          .subscribe(res => {
                this.loginRes = res;
                console.log(this.loginRes);
            }, (err) => {
              console.log(err);
            }
          );
     }
    

    Then called on it on click in my component template.

    Hope this helps others in my situation!