TypeError: Socket is not a constructor

2019-08-27 17:24发布

问题:

I'm new to Angular/Node and cannot seem to figure out a problem I'm having.

I'm trying to connect to an ftp using client-ftp and am having trouble with the implementation. Essentially I'm creating a button on the front end like this:

<button class="btn btn-primary" (click)="downloadFile()"><i class="fa fa-file-photo-o"></i> Download Screenshot</button>

And implementing trying to implement it via a click event like this:

downloadFile(){
    console.log('Connecting to sftp...');
    var ftpClient = require('ftp-client'),
        config = {
            host: 'localhost',
            port: 22,
            user: 'anonymous',
            password: 'anonymous'
        },
        options = {
            logging: 'basic'
        },
        client = new ftpClient(config, options);

    console.log('Downloading Screenshot...');
    client.connect(function () {
        client.download('/sftFilepPath', './Downloads', {
            overwrite: 'none'
        }, function (result) {
            console.log(result);
        });
    });
}

I keep getting an error, however saying: TypeError: Socket is not a constructor whenever the button is pressed. I'm getting both of my console.log() calls to show in the debugger so I assume it has to do with where I'm trying to actually connect and download.

I tried calling import for the FtpClient namespace and making a private client parameter in the constructor and working off of that, but that doesn't seem to work either.

I know a constructor is implicitly called by the new keyword, but I don't reference 'Socket' anywhere in my code. Maybe I'm missing something?

Here is my imports and constructor for reference:

import { Component, ElementRef, Input, OnInit, OnDestroy } from '@angular/core';
import { TestInstance, Test, TestDetails } from '../../objModules/index';
import { RunServices } from './run.services';
import { Observable } from 'rxjs/Rx';
import * as $ from 'jquery';
import * as _ from 'underscore';
import { ModalController } from './run.modal.controller';
// import { FtpClient } from 'ftp-client';

@Component({
    templateUrl: './run.modal.component.html',
    moduleId: module.id.toString(),
    selector: 'app-test-data',
    providers: [ RunServices ]
})

export class ModalComponent implements OnInit, OnDestroy {
    testInstance: TestDetails;
    id: string;
    private element: JQuery;

    private runId: string;
    private test$: Observable<Test>;
    private testHistory$: Observable<TestInstance[]>;

    private test: Test;
    private testHistory: TestInstance[];
    private selectedTest: TestInstance;
    private latestRuns: TestInstance[];

    private averagePass: number;
    private averageFail: number;

    services: RunServices;

    constructor(private modalController: ModalController, private el: ElementRef, private runServices: RunServices) {
        this.element = $(el.nativeElement);
        this.services = runServices;

        // Initialize these objects so we don't get any errors
        this.test = new Test(' ', ' ', ' ', [' '], ' ', ' ');
        this.testHistory = new Array<TestInstance>(new TestInstance(' ', ' ', ' ', 0, ' ', ' ', ' ', ' ', ' '));
        this.testInstance = new TestDetails(' ', ' ', ' ', ' ', ' ', ' ', ' ', 0, null, ' ');
        this.selectedTest = new TestInstance(' ', ' ', ' ', 0, ' ', ' ', ' ', ' ', ' ');
    }

回答1:

My guess is that your ftp client is too old. System environments change more and more rapidly. But this client hasn't been updated since 2015. Try to use an up-to-date client like jsftp



回答2:

Initial Overview

There is an anomaly is your file path within the client.download method. The path /stfFilepPath seems to have an extra 'p'. Try removing it unless that is the actual name of the path.

So;

client.download('/sftFilepPath', './Downloads'

becomes

client.download('/sftFilePath', './Downloads'

Try it out and let me know if it works. If not try Lynx's solution.