Easiest way to create a subscription provider?


#1

I would like to create a simple service that listens to accelerometer data. How can I subscribe to these values from a page?

This is my page:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { AccelerometerProvider } from '../../providers/accelerometer/accelerometer';

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController, private accelerometer: AccelerometerProvider) {

  }

}

and this is my service:

import { Injectable } from '@angular/core';
import { DeviceMotion, DeviceMotionAccelerationData } from '@ionic-native/device-motion';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class AccelerometerProvider {

  constructor(private deviceMotion: DeviceMotion) {
    console.log('Hello AccelerometerProvider Provider');
  }

  start() {
    this.deviceMotion.watchAcceleration().subscribe((acceleration: DeviceMotionAccelerationData) => {
      let x = acceleration.x;
      let y = acceleration.y;
      let z = acceleration.z;
    });
  }

}

What I want is just have access to x, y, z values from my page, each time a new subscription comes.
I suppose it is a n ‘observable’ thing but I am fairly new to this technology. I would appreciate any help.


#2

Providers generally should be providing observables, not subscribing to them. How about making start() simply return the result of watchAcceleration() and doing the subscribing in the page?


#3

Well, the problem is that I dont just want to subscribe to the raw accelerometer values. I wanna process these values in the service and send subscriptions to the page with the processed values.

Let’s say for example, I wanna get the acceleration vector.

v = Math.sqrt(acceleration.x * acceleration.x + acceleration.y * acceleration.y + acceleration.z * acceleration.z)

if (v > thresh) {
    //send info to page
}

How can I subscribe to this from my page? I think that the above logic should be implemented in a service, not directly in the page.


#4

You can use the pipe method and RxJS operators to modify the observable. In your service, you could map the observable from device motion so that it provides the data in the format that you would like to use it in. Have your service return this mapped observable, and then you can subscribe to it from wherever you need.

EDIT: For reference: https://www.learnrxjs.io/operators/transformation/map.html


#5

Thank you Josh! Your help is always appreciated!

I know I can alter the subscription data through ‘map’ but what if I want the data to be send ONLY when a condition is satisfied? Like the above example (when v is greater than a thresh). Is there such a way or will the observable constantly send new data?


#6

Use BehaviorSubject


#7

rxjs filter operator.