3

New to observables. I'm using ssh2 to get a list of files/folders on my server. I can't figure out how to get my data back as an observable since all of the examples of online use http rather than a 3rd party module.

How can I set this service up so that I can get the list back as an observable?

import {Injectable, NgZone} from '@angular/core';
import {Observable} from 'rxjs';
var Client = require('ssh2').Client;
var user = require('credentials.json')
@Injectable()
export class ConnectionService {
    public connSettings:any;

    constructor(private zone: NgZone){
        this.connSettings = {
            host: user.url,
            username: user.username,
            password: user.password
        };
        this.openConnection();

    }
    openConnection() {
        let remotePathToList = '/home/user';
        var conn = new Client();

        conn.on('ready', ()=>{
            conn.sftp((err:any, sftp:any)=>{
                if (err) throw err;
                sftp.readdir(remotePathToList, (err:any, list:any)=>{
                    conn.end();

                    //return observable data here

                    return list;

                })
            })
        }).connect(this.connSettings);

    }


}

1 Answer 1

1

If you want a generic attribute to access the list at any time (unrelated to the openConnection()-method, you could use a ReplaySubject:

@Injectable()
export class ConnectionService {
    public yourList$: ReplaySubject<any> = new ReplaySubject<any>(1);
    public connSettings:any;

    constructor(private zone: NgZone){
        this.connSettings = {
            host: user.url,
            username: user.username,
            password: user.password
        };
        this.openConnection();

    }
    openConnection() {
        let remotePathToList = '/home/user';
        var conn = new Client();

        conn.on('ready', ()=>{
            conn.sftp((err:any, sftp:any)=>{
                if (err) throw err;
                sftp.readdir(remotePathToList, (err:any, list:any)=>{
                    conn.end();

                    //return observable data here
                    yourList$.next(list);
                    return list;

                })
            })
        }).connect(this.connSettings);
    }
}

If you want to only have it as a returned Observable of the openConnection you could create a custom Observable:

@Injectable()
export class ConnectionService {
    public yourList$: ReplaySubject<any> = new ReplaySubject<any>(1);
    public connSettings:any;

    constructor(private zone: NgZone){
        this.connSettings = {
            host: user.url,
            username: user.username,
            password: user.password
        };
        this.openConnection();

    }
    openConnection(): Observable<any> {
        return Observable.create(obs => {
            let remotePathToList = '/home/user';
            var conn = new Client();

            conn.on('ready', ()=>{
                conn.sftp((err:any, sftp:any)=>{
                    if (err) throw err;
                    sftp.readdir(remotePathToList, (err:any, list:any)=>{
                        conn.end();

                        //return observable data here
                        obs.next(list);
                        obs.complete(); // required, otherwise your subscription would never close
                    })
                })
            }).connect(this.connSettings);
        });
    }
}

Please note, that with the 2nd solution, you will have to call subscribe on openConnection otherwise nothing will happen, since it is now wrapped inside an observable:

connectionService
    .openConnection()
    .subscribe(list => console.log(list));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.