Angular2 - stop / cancel / clear observable in routerOnDeactivate() [duplicate] - service

This question already has an answer here:
End Observable interval when route changes in Angular
(1 answer)
Closed 6 years ago.
I'm new to Angular2 so apologies if this is a trivial question. I can't seem to stop interval when I click to a different link. This component fetches data from DB table every 3,5s and it is used as a chat, so 100 users can add to it at any point. I don't want this to run in the background all the time, so I thought I'll use routeronDeactivate() function to make it stop when user is on a different link.
I think I'm doing something wrong. Can anyone help me please?
export class FeedComponent {
public feeditems: Feed[];
public timer;
constructor(private _feedService: FeedService) {
}
getArticlesJSON() {
console.log('getArticlesJSON');
this._feedService.getFeedJSON()
.subscribe(
data => this.feeditems = data,
err => console.log(err),
() => console.log('Completed')
);
}
routerOnDeactivate() {
// this.timer.remove();
// this.timer.dematerialize();
// clearInterval(this.timer);
console.log('-- deactivate ');
// console.log('-- deactivate ' + JSON.stringify(this.timer));
}
routerOnActivate() {
this.timer = Observable.timer(5000,3500);
this.timer.subscribe(() => {
this.getArticlesJSON();
});
console.log('++ activate ' + JSON.stringify(this.timer));
}
}

routerOnActivate() {
this.timer = Observable.timer(5000,3500);
this.subscription = this.timer.subscribe(() => {
this.getArticlesJSON();
});
}
routerOnDeactivate() {
this.subscription.unsubscribe();
}

Related

Ionic 5 | Detect app closing or going to background

I Cannot detect when the app is closing or going to background on ionic 5. Pause event is not working. What i tried is this:
ionViewDidLoad() {
this.pause = this.platform.pause.subscribe(() => {
this.experimentService.stop().then(res => {
//I do something that doing things to a raspberry pi (don't know if that matters), that take some time to respond
});
});
}
ionViewWillLeave() {
this.pause.unsubscribe();
}
Thanks to #E. Maggini comment, the problem was that I did not use async.
Solution:
this.platform.pause.subscribe(async () => {
this.experimentService.stop().then(res => {
});
});

How to "break" a Observable and jump to another page in Ionic?

sorry for the confusing question. So currently i'm working with this block of code in Ionic, it looks like this:
home.ts :
ionViewDidLoad() {
this.myFunction().subscribe()( data => {
// Do some stuff here, then
// open another page/modal with the data received
this.openModal(anotherPage,data);
}
}
The problem, I believe, is that I have to do something to "unsubscribe" my current function since it's being called every second. I tried putting the whole code in the ionViewDidLoad, believing that when it jumps to another page the function will be suspended but it just doesn;t work.
openModal(zone) {
let modal = this.modalCtrl.create(ZonePage, { 'zone': zone });
modal.present();
}
Any idea to solve this situation?
one solution could be:
ionViewDidLoad() {
let sub = this.myFunction().subscribe( data => {
// Do some stuff here, then
// open another page/modal with the data received
sub.unsubscribe();
this.openModal(anotherPage,data);
}
}
another one (when you know how often it emits before it you trigger your modal):
ionViewDidLoad() {
this.myFunction().take(10).subscribe( data => {
// Do some stuff here, then
// open another page/modal with the data received
this.openModal(anotherPage,data);
}
}

prevent multiple posts in react/mongoose

I'm working on an app in reactjs/redux with mongoose. I have form which allows to auth ppl add a comment to the article but if user clicks like 10 times in 1 second form gonna send 10 requests.. which is bad. How can I prevent this?
Let's say user clicks once on a button and then he needs to wait 5 seconds to send another comment.
As for the frontend part, you can add a timestamp to the component state or redux, something like lastPostTime for that user and then compare it to the current time and if it's less than 5 seconds or other timeframe that you want to prevent the post, make the button disabled.
Here is some imaginary component example:
class App extends Component {
constructor() {
super();
this.state = {
lastPostTime: null
};
this.handleCommentSubmit = this.handleCommentSubmit.bind(this);
this.checkIfTimeoutPassed = this.checkIfTimeoutPassed.bind(this);
}
handleCommentSubmit(e) {
if (this.checkIfTimeoutPassed()) {
console.log('sent');
this.setState({ lastPostTime: Date.now() });
}
}
checkIfTimeoutPassed() {
const postTimeOut = 5000;
const { lastPostTime } = this.state;
const timeSinceLastPost = Date.now() - lastPostTime;
return !lastPostTime || timeSinceLastPost > postTimeOut;
}
render() {
return (<button onClick={this.handleCommentSubmit}>Click me</button>);
}
}
It would make sense to make a similar checks on the backend in case the user will hack through the frontend limitations.

Ionic2: Unsubscribe Event to Avoid Duplicate Entries?

I've followed this tutorial which outlines adding monitoring beacons in an Ionic 2 application. I have it working great: when the view loads, it initializes and begins listening for beacons:
home.ts
ionViewDidLoad() {
this.platform.ready().then(() => {
this.beaconProvider.initialise().then((isInitialised) => {
if (isInitialised) {
this.listenToBeaconEvents();
}
});
});
}
This calls the listenToBeaconEvents function which populates a list in the view with all of the beacons:
home.ts
listenToBeaconEvents() {
this.events.subscribe(‘didRangeBeaconsInRegion’, (data) => {
// update the UI with the beacon list
this.zone.run(() => {
this.beacons = [];
let beaconList = data.beacons;
beaconList.forEach((beacon) => {
let beaconObject = new BeaconModel(beacon);
this.beacons.push(beaconObject);
});
});
});
}
I'm able to stop ranging using this.beaconProvider.stopRanging() that calls a function from the below function:
beacon-provider.ts
stopRanging() {
if (this.platform.is('cordova')) {
// stop ranging
this.ibeacon.stopRangingBeaconsInRegion(this.region)
.then(
() => {
console.log('Stopped Ranging');
},
error => {
console.error('Failed to stop monitoring: ', error);
}
);
}
}
The problem I'm having is this - in the original tutorial the beacon list is shown at the root, there's no other navigation. I've moved it to a different view, and if the user exits and re-enters the view, it re-initializes and loads everything, resulting in duplicate list entries.
I've tried creating a function within beacon-provider.ts to call before the view exits, but I can't figure out how to keep the subscriptions/events from duplicating.
I've tried this.delegate.didRangeBeaconsInRegion().unsubscribe(), and some other variations but they all result in runtime errors.
In your case you are using Ionic's Events API which has its own unsubscribe(topic, handler) function.
In your component, whenever you need to unsubscribe, you should call this with the same topic:
this.events.unsubscribe(‘didRangeBeaconsInRegion’);
This will remove all handlers you may have registered for the didRangeBeaconsInRegion.
If you want to unsubscribe one specific function, you will have to have registered a named handler which you can send with unsubscribe.
this.events.unsubscribe(‘didRangeBeaconsInRegion’,this.mySubscribedHandler);
And your home.ts would look like:
mySubscribedHandler:any = (data) => {
// update the UI with the beacon list
this.zone.run(() => {
this.beacons = [];
let beaconList = data.beacons;
beaconList.forEach((beacon) => {
let beaconObject = new BeaconModel(beacon);
this.beacons.push(beaconObject);
});
});
}
listenToBeaconEvents() {
this.events.subscribe(‘didRangeBeaconsInRegion’,this.mySubscribedHandler);
}

Soundcloud API sc.stream (track not loading on mobile sometime) - working on desktop

We are currently using the soundcloud API SDK for streaming and it does work on desktop but not 100% on mobile. (using responsive html. same api of course)
Sometime track is not lauch ? sometime it is.
I do not have specific error but on chrome network this line is show in red ??
http://api.soundcloud.com/tracks/146926142/stream?client_id=XXXXX
Redirect
We use a function to stream the track.
function streamTrack(id) {
var defer = $q.defer();
// Stream the track
SC.stream('/tracks/' + id, {
useHTML5Audio: false,
waitForWindowLoad: true,
onfinish: _scope.next,
whileplaying: function () {
var _this = this;
// Since we are in a callback, we need to tell angularJS to apply the change
if (timeout1) $timeout.cancel(timeout1);
timeout1 = $timeout(function () {
// Update the progress bar
_scope.progress = (_this.position / currentTrackDuration * 100) + '%';
_scope.timer = moment(_this.position).format('mm:ss');
$rootScope.$broadcast('trackRunning', { timerunning: _scope.timer });
});
}
}, function (sound) {
if (sound) {
defer.resolve(sound);
} else {
defer.reject();
}
});
return defer.promise;
}
If somebody has an idea pls.
Best Regards
Xavier