javascript - Create Observable that displays once or updates without duplication -


i'm making ionic app geolocation, geolocation handled firebase geofire library handling havershine formula (geo location) calculations.

ive reworked following work typescript (http://jsfiddle.net/katowulf/9geff/), merges 2 firebase tables/collections (theres more 2 being joined leaving them out brevity) , desired result feed these homepage component show users close by.

i understand concepts of angular ill admit struggle executing observables , rxjs whole successfully, either attempts duplicate data in array, or when value gets updated duplicates in view etc or else doesnt work - ive come across these scenarios multiple times think out lot of people if pro angular guy can shed light on this..

my first function listusers gets current active users lattitude/long , feeds geofire query iterates on database gathering other latt/long within 20 mile radius.

this feeds user ids 1 @ time loaduser function specifies tables join etc , and executes joinpaths function data gathering , object merging magic happens...

this outputs data this.show(mergedobject) able grab data in template i'm unsure how this, ive tried observable.of, observable.from etc either data doesnt display in template or mentioned before duplicates data...

any genius out there have ideas on how working flawlessly ? literally 1 thing holds me apps.

i think because iterates on each user thats nearby cause issues observables - need gathers results , when has done create array can fed home component, i'm happy not have list update in real time @ stage, better ux perspective anyway let users pull update wish.

// service component

    public joinpaths(id, paths, callback) {         let returncount = 0;         let expectedcount = paths.length;         let mergedobject = {};         paths.foreach( (p) => {             this.fb().database().ref(p).child(id).once('value',                 // success                  (snap) => {                      this.extendobj(mergedobject, snap.val());                      if (++returncount === expectedcount) {                         this.show(mergedobject);                     }                 },                 (error) => {                     returncount = expectedcount + 1; // abort counters                     console.log( "error in joinpaths ", error );                 }             );         });     }      public loaduser(userid) {         this.joinpaths(userid, ['users', 'geofire'], this.show);     }      public show(obj?): observable<any> {        return observable.of( obj );     }      public listusers() {             this.fb().database().ref(`/users/${this.userid}/lastknownlocation`).once('value').then( (snapshot) => {                  this.geofire.query({ center: [snapshot.val().lat, snapshot.val().lng], radius: 20  }).on( "key_entered", (key, location, distance) => {                 this.loaduser(key);             });         });            }       // merge tables data 1 object     private extendobj<t1,t2>(obja: t1, objb: t2) {         for(let key in objb){             if(objb.hasownproperty(key)){                 (obja any)[key] = (objb any)[key];             }         }             return <t1&t2>obja;     } 

// home.ts

import { component, ngzone } '@angular/core'; import { navcontroller, popovercontroller } 'ionic-angular'; import { geoapi } '../../providers/geo'; import { observable } 'rxjs/observable'; import { storage } '@ionic/storage';  @component({   selector: 'page-home',   templateurl: 'home.html' }) export class homepage {  public users$: observable<any>;    constructor( public _api: geoapi ) {                                                  this._api.listusers();           this.users$ = this._api.show();     }   } 

// home.html

    <ion-header>         <ion-navbar>             <ion-title>home</ion-title>         </ion-navbar>     </ion-header>      <ion-content padding>      <ion-grid>             <ion-col *ngfor="let c of users$" class="member-item" tappable width-33>                                       <ul class="o-list-reset c--user">                 <li class="c-username o-center c-uname">{{ c?.firstname }}</li>             </ul>         </ion-col>          </ion-grid>        </ion-content> 

and on each iteration of these functions users data similar following fed final function show()

    {         // geofire table/collection data merged         "g": "u2fkbvz3rk",         "l": [             51.085535799999995,             13.457294699999998         ],         // users table/collection data merged         "profile": {             "about": {             "avatarurl": "assets/img/generic.png",             "birthday": "2015-01-01",             "blockedby": "",             "email": "janek@gmail.com",             "firstname": "janek",             "gender": "female",             "id": "yrduxr1dlmoypj6kcd2ss55gfd4",             "isdeleted": 0,             "isfacebooklinked": "",             "isverified": 0,             "lastknownlocation": {                 "lat": 51.085535799999995,                 "lng": 13.457294699999998             },                     },         } 


Comments

Popular posts from this blog

resizing Telegram inline keyboard -

command line - How can a Python program background itself? -

php - "cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux -