Representing the map pins

It's all very well us being able to save the pins to the database, but we also need a way to represent the pins on the map so that we can show them during the map session and move them as needed. This class will also act as the connection to the data service. The class that we are going to write will demonstrate a neat little trick introduced in TypeScript 3, called rest tuples, and starts off as follows:

export class PinsModel {
private pins: PinModelData[] = [];
constructor(private firebaseMapService: FirebaseMapService) { }
}

The first feature we are going to introduce deals with adding the data for a pin when the user clicks on the map. The signature for this method looks a little bit strange, so we'll take a minute or so to cover how it works. This is what the signature looks like:

public Add(...args: [string, string, ...number[]]);

When we see ...args as the last (or only) parameter, our immediate thought here is that we are going to be using a REST parameter. If we break the parameter list down from the start, we can think of this as starting off like this:

public Add(arg_1: string, arg_2: string, ...number[]);

That almost looks like it makes sense, but there's another REST parameter in there. This basically says that we can have any number of numbers at the end of the tuple. The reason that we have to apply ... to this, rather than just applying number[], is because we need to spread the elements out. If we just used the array format, we would have to push elements into this array in the calling code. With the REST parameter in the tuple, we can pull the data out, save it to the database, and add it to our pins array, like this:

public Add(...args: [string, string, ...number[]]) {
const data: PinModelData = {
id: args[0],
name: args[1],
lat: args[2],
long: args[3],
storageId: ''
};
this.firebaseMapService.Save(data);
this.pins.push(data);
}
The implication of using a tuple like this is that the calling code has to make sure that it is putting values into the correct location.

When we get to the code to call this, we can see that our method is called as follows:

this.pinsModel.Add(guid.toString(), geocode, e.location.latitude, e.location.longitude);

When the user moves a pin on the map, we will use a similar trick to update its location. All we need to do is find the model in our array and update its values. We even have to update the name because the act of moving the pin will change the address of the pin. We call the same Save method on our data service just like we did in our Add method:

public Move(...args: [string,string, ...number[]]) {
const pinModel: PinModelData = this.pins.find(x => x.id === args[0]);
if (pinModel) {
pinModel.name = args[1];
pinModel.lat = args[2];
pinModel.long = args[3];
}
this.firebaseMapService.Save(pinModel);
}

Other classes will need access to the data from the database too. We face two choices here—we could either have other classes also use the Firebase map service and potentially miss out calls to this class, or we could make this class the sole point of access to the map service. We are going to rely on this class to be the single point of contact with FirebaseMapPinsService, which means that we need to expose the model through a Load method:

public Load(): Observable<PinModelData[]>{
return this.firebaseMapService.model;
}

Removing a point of interest uses a much simpler method signature than adding or moving one. All we need is the client-side id of the record, which we use to find the PinModelData item and call Delete to remove from Firebase. Once we have deleted the record, we find the local index of this record and remove it by splicing the array:

public Remove(id: string) {
const pinModel: PinModelData = this.pins.find(x => x.id === id);
this.firebaseMapService.Delete(pinModel);
const index: number = this.pins.findIndex(x => x.id === id);
if (index >= 0) {
this.pins.splice(index,1);
}
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.243.184