Использование Async в Angular Services - PullRequest
0 голосов
/ 26 октября 2018

Итак, у меня есть две службы и один компонент ниже.

Это ros.service.ts, он устанавливает соединение с моим сервером

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

@Injectable({
  providedIn: 'root'
})
export class RosService {

  // Creates object with the ROS library
  // @ts-ignore <= Makes ts happy, wont error
  ros = new ROSLIB.Ros({
      // Set listen URL for ROS communication
      url : 'ws://localhost:9090'
  });

  initialize() {
      let data;
      // Listens for error from ROS and logs it
      this.ros.on('error', function(error) {
          console.log(error);
      });

      // Find out exactly when we made a connection.
      this.ros.on('connection', function() {
          console.log('Connection made!');
      });
      // Logs when connection is closed
      this.ros.on('close', function() {
          console.log('Connection closed.');
      });
  }
}

// Data is gotten through subscription from each node service
// this.driveControlService.getDriveControlData().subscribe(msg => {
//   this.data = msg;
//   console.log(msg);
// });
// }

Далее, это сервис, вызываемый из подмножества сервера (или узла для тех, кто имеет опыт работы с ROS) ms5837.service.ts

import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import '../../assets/roslib.js';

@Injectable({
  providedIn: 'root'
})
export class Ms5837Service {
  // Creates object with the ROS library
  // @ts-ignore <= Makes ts happy, wont error
  ros = new ROSLIB.Ros({
    // Set listen URL for ROS communication
    url : 'ws://localhost:9090'
  });
  // Define subject to hold data values
  ms5837: BehaviorSubject<any> = new BehaviorSubject(1);
  // Initializer to be called every time BMP280 is going to be used
  initialize() {
    // Get Data from ROS bmp280 Topic
    // @ts-ignore
    const ms5837Listener = new ROSLIB.Topic({
      ros: this.ros,
      name: '/rov/ms5837',
      messageType: 'ms5837/ms5837_data'
    });

    // Subscribe to bmpListener
    ms5837Listener.subscribe((message) => {
      console.log('Recieved Message on ' + ms5837Listener.name + ' : ' + message);
      // console.log(message);
      this.ms5837.next(message);
    });
  }
  // Define data getter
  getData(): Observable<any> {
    if (this.ms5837) {
      return this.ms5837.asObservable();
    }
  }
}

И, наконец, я пытаюсь получить данные в этом компоненте и назначить их данным для использования в графике. telemetrydata.component.ts

import {OnInit, Component, AfterViewInit} from '@angular/core';
import { Chart } from 'chart.js';
import { Ms5837Service } from '../../../services/ms5837.service';
import { Ms5837Data } from '../../../services/data-models/ms5837.model';

@Component({
  selector: 'app-depth-chart',
  templateUrl: './depth-chart.component.html',
  styleUrls: ['./depth-chart.component.css']
})
export class DepthChartComponent implements OnInit {
    exteriorAltitude = [0];
    seconds = [0];
    name = 'Depth Chart';
    type = 'line';
    data = {
        labels: this.seconds,
        datasets: [{
            label: 'Depth',
            data: this.exteriorAltitude,
            backgroundColor: [
                'rgba(0,188,212, .3)'
            ],
            borderColor: [
                '#00bcd4'
            ],
            borderWidth: 1
            }]
    };
    options = {
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    };
    constructor(private ms5837Service: Ms5837Service) {}
    ngOnInit() {
        this.ms5837Service.initialize();
        this.ms5837Service.getData().subscribe((msg: Ms5837Data) => {
            if (msg !== undefined) {
              console.log(msg);
              this.exteriorAltitude.push(msg.altitudeM);
              console.log(this.exteriorAltitude);
              this.seconds.push(msg.header.stamp.secs);
            }
        });
    }
}

В настоящее время для установления соединения с сервером требуется немного времени, поэтому первое значение, передаваемое через наблюдаемое в telemetrydata.component.ts, не определено, что приводит к аварийному завершению. Я попытался поиграть с async и обещанием, но, честно говоря, я не достаточно опытен с rxjs, чтобы сделать это. Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

Проблема волшебным образом решена сама собой (?) Итак, проблема решена, я полагаю.

0 голосов
/ 26 октября 2018

Я собираюсь сделать удар в этом и надеюсь, что мой ответ будет полезным.

Похоже, вам не нужны обе услуги, чтобы сделать эту работу ... Я ошибаюсь?Я не вижу вашего конструктора для вашего второго сервиса, но я не вижу, где вы используете первый сервис.Тем не менее, я собираюсь посмотреть только на второй сервис и компонент.

Сервис

import { Injectable } from '@angular/core';
import {BehaviorSubject, Observable} from 'rxjs';
import '../../assets/roslib.js';

@Injectable({
  providedIn: 'root'
})
export class Ms5837Service {
  ros = new ROSLIB.Ros({
    // Set listen URL for ROS communication
    url : 'ws://localhost:9090'
  });

  // Here I am just returning the observable from ROS

  getData(): Observable<Any> {
    return new ROSLIB.Topic({
          ros: this.ros,
          name: '/rov/ms5837',
          messageType: 'ms5837/ms5837_data'
        });
  }
}

Компонент

import {OnInit, Component, AfterViewInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs';
import { Chart } from 'chart.js';
import { Ms5837Service } from '../../../services/ms5837.service';
import { Ms5837Data } from '../../../services/data-models/ms5837.model';

@Component({
  selector: 'app-depth-chart',
  templateUrl: './depth-chart.component.html',
  styleUrls: ['./depth-chart.component.css']
})
export class DepthChartComponent implements OnInit, OnDestroy {

    // adding a subscsription here
    rosData: Subscription;

    exteriorAltitude = [0];
    seconds = [0];
    name = 'Depth Chart';
    type = 'line';
    data = {
        labels: this.seconds,
        datasets: [{
            label: 'Depth',
            data: this.exteriorAltitude,
            backgroundColor: [
                'rgba(0,188,212, .3)'
            ],
            borderColor: [
                '#00bcd4'
            ],
            borderWidth: 1
            }]
    };
    options = {
        options: {
            responsive: true,
            maintainAspectRatio: false,
            scales: {
                yAxes: [{
                    ticks: {
                        beginAtZero: true
                    }
                }]
            }
        }
    };
    constructor(private ms5837Service: Ms5837Service) {}
    ngOnInit() {

        // this should fire every time the subscription receives a notice
        this.rosData = this.ms5837Service.getData().subscribe((msg: Ms5837Data) => {
            if (msg !== undefined) {
              console.log(msg);
              this.exteriorAltitude.push(msg.altitudeM);
              console.log(this.exteriorAltitude);
              this.seconds.push(msg.header.stamp.secs);
            }
        });
    }

    ngOnDestroy() {
      this.rosData.unsubscribe();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...