How to Read the RxJS 6 Sources: Map and Pipe

How to Read the RxJS 6 Sources: Map and Pipe

How to Read the RxJS 6 Sources : Understanding of() and Subscriptions ... I'll even simplify things further by commenting out pipe and map for now.

Disclaimer: This series is just my notes as I read through the RxJS sources. I’ll provide a summary of the main points at the end of the article, so don’t feel too bogged down with the details

Welcome back. Today I’m very excited, because I’m finally going to dig into how pipe is implemented in RxJS. This article will start with an overview of how map and pipe work, and then will delve into the RxJS sources.

Previously

In the last article, I looked into the of method for creating an observable. I’ll continue working off of that simple Stackblitz example, except this time, I’ll uncomment map and pipe. You don’t have to be familiar with the previous article to follow this one. Here’s the excerpt from Stackblitz:


map attack!

Here’s a link to the Stackblitz.

Before I dive into the sources, let’s talk about map and pipe. Before trying to read any source, it’s best to have a high-level understanding of how everything works. Otherwise, it’s too easy to get lost in the details.

I know these two things before going in:

  • map is an operator that transforms data by applying a function
  • pipe composes operators (like map, filter, etc)
Map

Map’s job is to transform things

map is a pretty simple operator. It takes a projection function, and applies it to each value that comes from the source observable.

In this example, the observable returned by of('World’) is the source observable, and the single value 'World' is going to be pipe'd through to map’s projection function, which looks like this:

x => `Hello ${x}!` // projection function
// It's used like this:
of('World').pipe(map(x => `Hello ${x}!`));

The projection function will receive 'World' as its input parameter x, and will create the string Hello World!.
map wraps the project function in an observable, which then emits the string value Hello World!. Remember, operators always return observables.

map wraps the projection function in an observable, and starts emitting string values.

I’ve written about the basics of map and other operators pretty extensively in this article. I’ll cover some of that material again here.

Basically, if you understand how Array.prototype.map works, most of that knowledge will carry over to observables.

We’ll see more on map later in this article. Let’s look at pipe next.

Pipe

pipe is the star of this article. Unlike map, which is an operator, pipe is a method on Observable which is used for composing operators. pipe was introduced to RxJS in v5.5 to take code that looked like this:

of(1,2,3).map(x => x + 1).filter(x => x > 2);

and turn it into this

of(1,2,3).pipe(
  map(x => x + 1),
  filter(x => x > 2)
);

Same output, same concept (composing operators), different syntax.
pipe offers the following benefits:

  • It cleans up Observable.prototype by removing operators
  • It makes the RxJS library more tree-shakeable
  • It makes it easier to write and use third-party operators (since you don’t have to worry about patching Observable.prototype).

Nicholas Jamieson provides a great explanation of the benefits of using pipe for composition in this article.

Quick detour (skip this section if you are comfortable with pipe)

If you’re unfamiliar with using pipe for composition, it’s worthwhile to see how it works on regular functions before seeing how it works with operators. Let’s look at a simplified version of pipe which acts on normal functions:

const pipe = (...fns) => 
           initialVal => 
           fns.reduce((g,f) => f(g), initialVal);

In this example, pipe is a function which accepts functions as arguments. Those arguments are collected into an array called fns through use of ES6 rest parameters (…fns). pipe then returns a function which accepts an initialValue to be passed into reduce in the following step. This is the value which is passed into the first function in fns, the output of which is then fed into the second function in fns, which is then fed into the third…and so on. Hence, a pipeline.
For example:

pipe.ts

const pipe = (...fns) => initialVal => fns.reduce((g,f) => f(g), initialVal);
const add1 = x => x + 1;
const mul2 = x => x * 2;

const res = pipe(add1,mul2)(0); // mul2(add1(0)) === 2

You can experiment with a simple pipe at this stackblitz link.

In RxJS, the idea is that you create a pipeline of operators (such as map and filter) that you want to apply to each value emitted by a source observable, of(1,2,3) in this example.

This approach lets you create small, reusable operators like map and filter, and compose them together when needed using pipe.

Composition is a pretty fascinating topic, although I can hardly do it justice.
I recommend Eric Elliott’s series on the topic if you want to learn more.

Enough talk! Get to the Sources!

I’ll start by adding a debugger statement into map. This will give me access to map within the dev tools debugger, as well as a way to step up into pipe.

and, in the dev tools:

Now that I’m oriented in the call stack, and I can start to dig around.

Notice that in the call stack, it’s Observable.subscribe that’s kicking everything off. Because observables tend to be lazy, no data will flow through the pipe and map until we subscribe to the observable.

var sub = source.subscribe(...)

Looking inside of map, I notice that MapOperator and MapSubscriber look interesting:

On line 55, source is the observable produced by of('World'). It is subscribed to on line 56, causing it to emit its one value, 'World', and then complete.

On line 56, an instance of MapSubscriber is created, and passed into source.subscribe. We’ll see later that the projection function is invoked inside of MapSubscriber’s _next method.

On line 56, this.project is the projection function passed into map:

and this.thisArg can be ignored for now. So line 56 is doing the following:

return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
  1. calling subscribe on source, which is the observable returned by of('World').
  2. The observer ( next, error, complete, etc) which is passed into source.subscribe is going to be the Subscriber returned by MapSubscriber, which takes the current subscriber, and the project function passed into map as its arguments.

As a quick aside, this is a very common pattern for operators in RxJS. In fact, they all seem to follow the following template:

  • export a public function, like map or filter or expand.
  • export a class which implements Operator, such as MapOperator. This class implements Operator call method. It subscribes to the source observable, like
    return source.subscribe(new MapSubscriber(…));
    This links the observables into a subscriber/observer pipeline.
  • A class which extends Subscriber. This class will implement methods such as _next.
    This is where the logic that makes each operator unique lives. For example, in map, the projection function will be invoked inside of MapSubscriber’s _next method. In filter the predicate function will be invoked inside of FilterSubscriber’s _next method, and so on.

I’ll provide an example of how to write your own operator in a future article (although it’s usually easier to just pipe together existing operators). In the meantime, the RxJS sources provide a nice guide here, and Nicholas Jamieson has a great example in this article.

Anyways, back to the debugging session.

Eventually, once subscribe is called, MapSubscriber._next will be invoked.

Notice that the projection function, project, which was passed into map is invoked on line 81, and the results (in this case 'Hello World!' ) will be returned, and then passed into this.destination.next(result) on line 86.


stepping into this.project.call puts us in the lambda we passed into the call to map

This explains how map applies the projection function to each value emitted by the source observable when it is subscribed to. That’s really all there to this step. If there were another operator in the pipeline, the observable returned by map would be fed into it.

This is a good example of how data flows through a single operator. But how does it flow through multiple operators…

Pipe (again)

To answer that, I must dig into pipe. It’s being invoked on the observable which is returned from of('World').

pipeFromArray is called on line 331 with operations, which is an array of all operators passed into pipe. In this case, it’s just the lonely map operator:

operations could hold many, many operators

The function returned from the call to pipeFromArray(operations) is invoked with this, which is a reference to the observable returned from of('World').

Since there is only one operator in this case (map), line 29 returns it.

Line 33 is interesting. It’s where all of the operators passed into pipe are composed using Array.prototype.reduce. It’s not invoked in situations where it is passed only one operator (perhaps for performance reasons?).

Let’s look at a slightly more complex example, with multiple map operators.

Multiple maps

Now that I have an understanding of what map and pipe are doing, I’ll try a more complicated example. This time, I’ll use the map operator three times!

Hello World of RxJS

The only real difference is that pipe will use reduce this time:

The input variable is still the observable returned from of('World').

By stepping through each function in fns as it is called by reduce, I can see the string being built up as it passes through each one of the map operators. Eventually producing the string Hello World of RxJS

With an understanding of how data flows through a single operator, it’s not hard to extend that understanding to multiple operators.

A little map and a little filter

Just for fun, I want to throw filter in the mix. The goal here is to confirm that map isn’t unique. I want to see that all operators follow that similar pattern.


Will log values 3 and 4

In this example, of(1,2,3) will return an observable which, upon subscription, will emit three separate values, 1, 2, and 3, and will then complete. Each of these three values will be fed into the pipeline one at a time. map will add one to each, and then re-emit the new values one-by-one on the observable it returns. filter subscribes to the observable returned by map, and runs each value through its predicate function ( x => x > 2 ). It will return an observable which emits any value which is greater than 2. In this case, it will emit values 3 and 4.

If you want to see a more detailed explanation of the subscriber chain and how operators subscribe to one another,

Summary
  • We’ve seen that operators like map and filter are functions which take in and return observables.
  • Each operator exposes a public function like map or filter, which is what we import from 'rxjs/operators' and pass into pipe.
  • Each operator has a *Operator class which implements the Operator interface, so that it can subscribe to other observables.
  • Each operator has a *Subscriber class which contains the logic for that operator (invocation of the projection function for map, invocation of the predicate function for filter, etc).
  • We’ve also seen how pipe is used to compose operators together. Internally, it’s taking the values emitted by the source observable, and reducing it over the list of operators.

In the next article, I’ll look at some more advanced maps, and see how higher order observables are implemented. 🗺

A simple RxJS 6 example line by line to see how Map and Pipe work

A simple RxJS 6 example line by line to see how Map and Pipe work

In this article, I'll step through a simple RxJS example line by line to see how map and pipe work. Along the way, we'll see how an operator is

Disclaimer: This series is just my notes as I read through the RxJS sources. I’ll provide a summary of the main points at the end of the article, so don’t feel too bogged down with the details

Welcome back. Today I’m very excited, because I’m finally going to dig into how pipe is implemented in RxJS. This article will start with an overview of how map and pipe work, and then will delve into the RxJS sources.

Previously

In the last article, I looked into the of method for creating an observable. I’ll continue working off of that simple Stackblitz example, except this time, I’ll uncomment map and pipe. You don’t have to be familiar with the previous article to follow this one. Here’s the excerpt from Stackblitz:

Here’s a link to the Stackblitz.

Before I dive into the sources, let’s talk about map and pipe. Before trying to read any source, it’s best to have a high-level understanding of how everything works. Otherwise, it’s too easy to get lost in the details.

I know these two things before going in:

  • map is an operator that transforms data by applying a function
  • pipe composes operators (like map, filter, etc)
Map

Map’s job is to transform things

map is a pretty simple operator. It takes a projection function, and applies it to each value that comes from the source observable.

In this example, the observable returned by of('World’) is the source observable, and the single value 'World' is going to be pipe'd through to map’s projection function, which looks like this:

x => `Hello ${x}!` // projection function
// It's used like this:
of('World').pipe(map(x => `Hello ${x}!`));

The projection function will receive 'World' as its input parameter x, and will create the string Hello World!.
map wraps the project function in an observable, which then emits the string value Hello World!. Remember, operators always return observables.

map wraps the projection function in an observable, and starts emitting string values.

I’ve written about the basics of map and other operators pretty extensively in this article. I’ll cover some of that material again here.

Basically, if you understand how Array.prototype.map works, most of that knowledge will carry over to observables.

We’ll see more on map later in this article. Let’s look at pipe next.

Pipe

pipe is the star of this article. Unlike map, which is an operator, pipe is a method on Observable which is used for composing operators. pipe was introduced to RxJS in v5.5 to take code that looked like this:

of(1,2,3).map(x => x + 1).filter(x => x > 2);

and turn it into this

of(1,2,3).pipe(
  map(x => x + 1),
  filter(x => x > 2)
);

Same output, same concept (composing operators), different syntax.
pipe offers the following benefits:

  • It cleans up Observable.prototype by removing operators
  • It makes the RxJS library more tree-shakeable
  • It makes it easier to write and use third-party operators (since you don’t have to worry about patching Observable.prototype).

Quick detour (skip this section if you are comfortable with pipe)

If you’re unfamiliar with using pipe for composition, it’s worthwhile to see how it works on regular functions before seeing how it works with operators. Let’s look at a simplified version of pipe which acts on normal functions:

const pipe = (...fns) => 
           initialVal => 
           fns.reduce((g,f) => f(g), initialVal);

In this example, pipe is a function which accepts functions as arguments. Those arguments are collected into an array called fns through use of ES6 rest parameters (…fns). pipe then returns a function which accepts an initialValue to be passed into reduce in the following step. This is the value which is passed into the first function in fns, the output of which is then fed into the second function in fns, which is then fed into the third…and so on. Hence, a pipeline.
For example:

const pipe = (...fns) => initialVal => fns.reduce((g,f) => f(g), initialVal);
const add1 = x => x + 1;
const mul2 = x => x * 2;

const res = pipe(add1,mul2)(0); // mul2(add1(0)) === 2

pipe.ts

You can experiment with a simple pipe at this stackblitz link.

In RxJS, the idea is that you create a pipeline of operators (such as map and filter) that you want to apply to each value emitted by a source observable, of(1,2,3) in this example.

This approach lets you create small, reusable operators like map and filter, and compose them together when needed using pipe.

Composition is a pretty fascinating topic, although I can hardly do it justice.
I recommend Eric Elliott]’s series on the topic if you want to learn more.

Enough talk! Get to the Sources!

I’ll start by adding a debugger statement into map. This will give me access to map within the dev tools debugger, as well as a way to step up into pipe.

and, in the dev tools:

Now that I’m oriented in the call stack, and I can start to dig around.

Notice that in the call stack, it’s Observable.subscribe that’s kicking everything off. Because observables tend to be lazy, no data will flow through the pipe and map until we subscribe to the observable.

var sub = source.subscribe(...)

Looking inside of map, I notice that MapOperator and MapSubscriber look interesting:

On line 55, source is the observable produced by of('World'). It is subscribed to on line 56, causing it to emit its one value, 'World', and then complete.

On line 56, an instance of MapSubscriber is created, and passed into source.subscribe. We’ll see later that the projection function is invoked inside of MapSubscriber’s _next method.

On line 56, this.project is the projection function passed into map:

and this.thisArg can be ignored for now. So line 56 is doing the following:

return source.subscribe(new MapSubscriber(subscriber, this.project, this.thisArg));
  1. calling subscribe on source, which is the observable returned by of('World').
  2. The observer ( next, error, complete, etc) which is passed into source.subscribe is going to be the Subscriber returned by MapSubscriber, which takes the current subscriber, and the project function passed into map as its arguments.

As a quick aside, this is a very common pattern for operators in RxJS. In fact, they all seem to follow the following template:

  • export a public function, like map or filter or expand.
  • export a class which implements Operator, such as MapOperator. This class implements Operator call method. It subscribes to the source observable, like
    return source.subscribe(new MapSubscriber(…));
    This links the observables into a subscriber/observer pipeline.
  • A class which extends Subscriber. This class will implement methods such as _next.
    This is where the logic that makes each operator unique lives. For example, in map, the projection function will be invoked inside of MapSubscriber’s _next method. In filter the predicate function will be invoked inside of FilterSubscriber’s _next method, and so on.

I’ll provide an example of how to write your own operator in a future article (although it’s usually easier to just pipe together existing operators). In the meantime, the RxJS sources provide a nice guide here, and Nicholas Jamieson has a great example in this article.

Anyways, back to the debugging session.

Eventually, once subscribe is called, MapSubscriber._next will be invoked.

Notice that the projection function, project, which was passed into map is invoked on line 81, and the results (in this case 'Hello World!' ) will be returned, and then passed into this.destination.next(result) on line 86.

This explains how map applies the projection function to each value emitted by the source observable when it is subscribed to. That’s really all there to this step. If there were another operator in the pipeline, the observable returned by map would be fed into it.

This is a good example of how data flows through a single operator. But how does it flow through multiple operators…

Pipe (again)

To answer that, I must dig into pipe. It’s being invoked on the observable which is returned from of('World').

pipeFromArray is called on line 331 with operations, which is an array of all operators passed into pipe. In this case, it’s just the lonely map operator:

The function returned from the call to pipeFromArray(operations) is invoked with this, which is a reference to the observable returned from of('World').

Since there is only one operator in this case (map), line 29 returns it.

Line 33 is interesting. It’s where all of the operators passed into pipe are composed using Array.prototype.reduce. It’s not invoked in situations where it is passed only one operator (perhaps for performance reasons?).

Let’s look at a slightly more complex example, with multiple map operators.

Multiple maps

Now that I have an understanding of what map and pipe are doing, I’ll try a more complicated example. This time, I’ll use the map operator three times!

The only real difference is that pipe will use reduce this time:

The input variable is still the observable returned from of('World').

By stepping through each function in fns as it is called by reduce, I can see the string being built up as it passes through each one of the map operators. Eventually producing the string Hello World of RxJS

With an understanding of how data flows through a single operator, it’s not hard to extend that understanding to multiple operators.

A little map and a little filter

Just for fun, I want to throw filter in the mix. The goal here is to confirm that map isn’t unique. I want to see that all operators follow that similar pattern.

Will log values 3 and 4

In this example, of(1,2,3) will return an observable which, upon subscription, will emit three separate values, 1, 2, and 3, and will then complete. Each of these three values will be fed into the pipeline one at a time. map will add one to each, and then re-emit the new values one-by-one on the observable it returns. filter subscribes to the observable returned by map, and runs each value through its predicate function ( x => x > 2 ). It will return an observable which emits any value which is greater than 2. In this case, it will emit values 3 and 4.

If you want to see a more detailed explanation of the subscriber chain and how operators subscribe to one another, I’ve written about it here.

Summary

  • We’ve seen that operators like map and filter are functions which take in and return observables.
  • Each operator exposes a public function like map or filter, which is what we import from 'rxjs/operators' and pass into pipe.
  • Each operator has a *Operator class which implements the Operator interface, so that it can subscribe to other observables.
  • Each operator has a *Subscriber class which contains the logic for that operator (invocation of the projection function for map, invocation of the predicate function for filter, etc).
  • We’ve also seen how pipe is used to compose operators together. Internally, it’s taking the values emitted by the source observable, and reducing it over the list of operators.

In the next article, I’ll look at some more advanced maps, and see how higher order observables are implemented. 🗺

JavaScript Map, Reduce, and Filter: What, Why and How to use it

JavaScript Map, Reduce, and Filter: What, Why and How to use it

Map, reduce, and filter are all array methods in JavaScript. In this JavaScript tutorial, you will learn what, why and how to use each one. Learn eight methods to iterate through an array in JavaScript! Methods include: forEach, map, filter, reduce, some, every, find, findIndex. Each one will iterate over an array and perform a transformation or computation. Each will return a new array based on the result of the function

JavaScript Map, Reduce, and Filter - Explained with Examples

Map, reduce, and filter are all array methods in JavaScript. Each one will iterate over an array and perform a transformation or computation. Each will return a new array based on the result of the function. In this article, you will learn why and how to use each one.

Here is a fun summary by Steven Luscher:

Map/filter/reduce in a tweet:

map([🌽, 🐮, 🐔], cook)
=> [🍿, 🍔, 🍳]

filter([🍿, 🍔, 🍳], isVegetarian)
=> [🍿, 🍳]

reduce([🍿, 🍳], eat)
=> 💩

Map

The map() method is used for creating a new array from an existing one, applying a function to each one of the elements of the first array.

Syntax

var new_array = arr.map(function callback(element, index, array) {
    // Return value for new_array
}[, thisArg])

In the callback, only the array element is required. Usually some action is performed on the value and then a new value is returned.

Example

In the following example, each number in an array is doubled.

const numbers = [1, 2, 3, 4];
const doubled = numbers.map(item => item * 2);
console.log(doubled); // [2, 4, 6, 8]
Filter

The filter() method takes each element in an array and it applies a conditional statement against it. If this conditional returns true, the element gets pushed to the output array. If the condition returns false, the element does not get pushed to the output array.

Syntax

var new_array = arr.filter(function callback(element, index, array) {
    // Return true or false
}[, thisArg])

The syntax for filter is similar to map, except the callback function should return true to keep the element, or false otherwise. In the callback, only the element is required.

Examples

In the following example, odd numbers are "filtered" out, leaving only even numbers.

const numbers = [1, 2, 3, 4];
const evens = numbers.filter(item => item % 2 === 0);
console.log(evens); // [2, 4]

In the next example, filter() is used to get all the students whose grades are greater than or equal to 90.

const students = [
  { name: 'Quincy', grade: 96 },
  { name: 'Jason', grade: 84 },
  { name: 'Alexis', grade: 100 },
  { name: 'Sam', grade: 65 },
  { name: 'Katie', grade: 90 }
];

const studentGrades = students.filter(student => student.grade >= 90);
return studentGrades; // [ { name: 'Quincy', grade: 96 }, { name: 'Alexis', grade: 100 }, { name: 'Katie', grade: 90 } ]
Reduce

The reduce() method reduces an array of values down to just one value. To get the output value, it runs a reducer function on each element of the array.

Syntax

arr.reduce(callback[, initialValue])

The callback argument is a function that will be called once for every item in the array. This function takes four arguments, but often only the first two are used.

  • accumulator - the returned value of the previous iteration
  • currentValue - the current item in the array
  • index - the index of the current item
  • array - the original array on which reduce was called
  • The initialValue argument is optional. If provided, it will be used as the initial accumulator value in the first call to the callback function.

Examples

The following example adds every number together in an array of numbers.

const numbers = [1, 2, 3, 4];
const sum = numbers.reduce(function (result, item) {
  return result + item;
}, 0);
console.log(sum); // 10

In the next example, reduce() is used to transform an array of strings into a single object that shows how many times each string appears in the array. Notice this call to reduce passes an empty object {} as the initialValue parameter. This will be used as the initial value of the accumulator (the first argument) passed to the callback function.

var pets = ['dog', 'chicken', 'cat', 'dog', 'chicken', 'chicken', 'rabbit'];

var petCounts = pets.reduce(function(obj, pet){
    if (!obj[pet]) {
        obj[pet] = 1;
    } else {
        obj[pet]++;
    }
    return obj;
}, {});

console.log(petCounts); 

/*
Output:
 { 
    dog: 2, 
    chicken: 3, 
    cat: 1, 
    rabbit: 1 
 }
 */

Map Custom Marker and Controls | JavaScript, CSS and API

Map Custom Marker and Controls | JavaScript, CSS and API

How we can add a custom marker on google map using JavaScript & CSS? Solution: JavaScript Google Map Marker With CSS, Custom API Map Controls.

Maybe you have seen custom markers on the map on some tour & travels websites. They show their all destination using those markers on the map. There are many online websites or services for creating custom markers, but we can also create those own using google map’s API. Google provides many kinds of API for developers on its Cloud Platform.

Today you will learn to add a custom marker on the map with your choosing place. This possible because of API, I am using jQuery & jQuery-Migrate for this program. As you know jQuery is a JavaScript library that’s why I am calling this a JavaScript Custom Map Marker Program. Suppose you have an online hotel booking site & you want to show all the places where your hotel is, then this will very useful for you.

So, Today I am sharing JavaScript Google Map Marker With CSSA Custom API Map Controls With JS & CSS. This program marker will place on given longitude & latitude. Its also has zoom in, zoom out, center, & full-screen buttons. There also is an option bar to choosing road view or satellite view. If you want to change the marker to other places, then you have just change the longitude & latitude.

If you are thinking now how this custom map marker actually is, then see the preview given below.

Preview Of Custom API Map Control

See this video preview to getting an idea of how this custom map with marker looks like.


Now you can see this visually. If you like this then get the source code of its.

Discussion

Before sharing source code, let’s talk about this. As you know I have used API, that runs the whole map’s function. I have used an image for the marker’s icon, after that placed on the chosen address in map. For placing the marker I have created some variables for the functions like whole map, long, lat, icon, etc.

All the functions like zoom, focus center, choosing satellite or road view are done by google’s provided API commands. There is another function is when you will click on the marker then the address will open in a new tab. You can remove this feature by removing the code in JS file, I have left a comment on every function’s code section. You can easily identify the codes are for your decided part.

In the CSS section, I have placed all the things you can see on the preview. Works like managing colors, positioning, etc are handled by CSS. As you can see all the buttons in the map are created using Font-Awesome icons. If you have good knowledge of HTML, CSS & JavaScript then you can understand the codes easily. These codes are looking tough but believe me that all are default functions of the API, I have just called on the right place.

For using it on your websites or project you just have to change the longitude & latitude on the JS file. If you get any trouble you can ask me on the comment section or direct message on the Facebook page.

JavaScript Google Map Marker With CSS Source Code

For creating this program you have create 3 files. First for HTML, second for CSS, & third for JavaScript. Follow the steps to creating this without any error.

index.html

Create an HTML file named ‘index.html‘ and put these codes given below.

<!DOCTYPE html>
<!-- code by webdevtrick ( https://webdevtrick.com )-->
<html lang="en" >
 
<head>
  <meta charset="UTF-8">
  <title>CSS Custom Marker On Map | Webdevtrick.com</title>
  
  <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'>
      <link rel="stylesheet" href="style.css">
</head>
 
<body>
 
  <div class="full-screen">
  <div id="map" class="map"></div>
 
    <!--controls-->
    <span id="zoomIn" class="btn zoom in">
        <i class="fa fa-plus"></i>
    </span>
    <span id="zoomOut" class="btn zoom out">
        <i class="fa fa-minus"></i>
    </span>
 
    <span id="center" class="btn zoom center">
        <i class="fa fa-crosshairs"></i>
    </span>
 
    <div class="mapTypeId">
        <select id="mapTypeId">
            <option value="1">Roadmap</option>
            <option value="2">Satellite</option>
        </select>
    </div>
 
</div>
  <script src='https://maps.googleapis.com/maps/api/js?key=AIzaSyCLFomDOPKqvvITt7tv_hZG0PDlWB2-q0g'></script>
<script src='https://code.jquery.com/jquery-1.11.3.min.js'></script>
<script src='https://code.jquery.com/jquery-migrate-1.2.1.min.js'></script>
 
    <script  src="function.js"></script>
 
</body>
</html>

style.css

Now create a CSS file named ‘style.css‘ and put these codes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85

/** code by webdevtrick ( https://webdevtrick.com ) **/
html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
}
.full-screen {
  position: relative;
  width: 100%;
  height: 100%;
}
.full-screen .map {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
}
.full-screen .btn {
  cursor: pointer;
  border: 0;
  border-radius: 2px;
  background-color: white;
  box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.1);
  transition: all 300ms ease-in-out;
}
.full-screen .btn.zoom {
  position: absolute;
  right: 20px;
  color: #e60023;
  font-size: 20px;
  padding: 5px 8px;
}
.full-screen .btn.zoom.in {
  top: 50%;
  margin-top: -37px;
}
.full-screen .btn.zoom.out {
  bottom: 50%;
  margin-bottom: -37px;
}
.full-screen .btn.zoom.center {
  top: 50%;
  margin-top: -87px;
}
.full-screen .btn.zoom:hover,
.full-screen .btn.zoom:active {
  color: white;
  background-color: #e60023;
}
.full-screen .btn.zoom:active {
  opacity: 0.75;
}
.full-screen .mapTypeId {
  position: absolute;
  top: 20px;
  left: 5px;
  border-radius: 2px;
  background-color: #e60023;
  box-shadow: 1px 1px 3px 0 rgba(0, 0, 0, 0.1);
  width: 90px;
  overflow: hidden;
  color: white;
  padding: 8px 0;
}
.full-screen .mapTypeId select {
  color: white;
  text-indent: 10px;
  text-transform: uppercase;
  font-weight: 700;
  width: 100%;
  position: relative;
  top: -2px;
  border: none;
  box-shadow: none;
  background-color: #e60023;
  background-image: none;
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
}
.full-screen .mapTypeId select:focus {
  outline: none;
}

function.js

The final step, Create a JavaScript file named ‘function.js‘ and put the codes.

/**code by webdevtrick ( https://webdevtrick.com ) **/
$(document).ready(function() {

var map;
var marker;
var lat = 28.7407056;
var lng = 77.0577493;
var ico = new google.maps.MarkerImage("https://webdevtrick.com/wp-content/uploads/location.png");

var overlay = new google.maps.OverlayView();
overlay.draw = function() {};	

function initialize () {
	var mapCanvas = document.getElementById('map');
	var mapOptions = {
	zoom: 13,
	center: {
	lat: lat, 

     lng: lng
},
mapTypeControl: false,
zoomControl: false,
panControl: false,
        scaleControl: false,
        streetViewControl: false,
        scrollwheel: false
}
 
map = new google.maps.Map( mapCanvas, mapOptions );
 
overlay.setMap(map);
   ZoomControl(map);
   addMarker(map);
  
}
 
// Marker
function addMarker ( map ) {
marker = new google.maps.Marker({
            map: map,
            draggable: false,
            icon: ico,
            position: new google.maps.LatLng( lat, lng )
        });
 
        mouseOverHandler = function () {
         showMarker(marker);
        }
        mouseClickHandler = function () {
         clickMarker(lat, lng);
        }
 
        google.maps.event.addListener( marker, 'click', mouseClickHandler );
        google.maps.event.addListener( marker, 'mouseover', mouseOverHandler );
}
 
// Marker Click
function clickMarker ( lat, lng ) {
var url = 'https://maps.google.com/maps?q='+lat+','+lng+'&z=18';
window.open(url, '_blank');
}
 
// Zoom
function ZoomControl ( map ) {
var zoomIn = document.getElementById('zoomIn');
var zoomOut = document.getElementById('zoomOut');
 
google.maps.event.addDomListener(zoomOut, 'click', function() {
var currentZoomLevel = map.getZoom();
if(currentZoomLevel != 0){
map.setZoom(currentZoomLevel - 1);}    
});
 
google.maps.event.addDomListener(zoomIn, 'click', function() {
var currentZoomLevel = map.getZoom();
if(currentZoomLevel != 21){
map.setZoom(currentZoomLevel + 1);}
});
}
 
// MapTypeId
function TypeIdChange ( option ) {
switch (option) {
            case "1":
                map.setMapTypeId( google.maps.MapTypeId.ROADMAP );
                break;
               case "2":
               map.setMapTypeId( google.maps.MapTypeId.SATELLITE );
                break;
            default:
                map.setMapTypeId( google.maps.MapTypeId.ROADMAP );
        }
}
// center
$( '#center' ).on( 'click', function () {
map.setZoom( 13 );
map.setCenter(new google.maps.LatLng( lat, lng ) );
map.setMapTypeId( google.maps.MapTypeId.ROADMAP );
$( '#mapTypeId' ).val( "1" ).trigger('click');
});
 
// center
$( '#center' ).on( 'click', function () {
map.setZoom( 13 );
map.setCenter(new google.maps.LatLng( lat, lng ) );
map.setMapTypeId( google.maps.MapTypeId.ROADMAP );
$( '#mapTypeId' ).val( "1" ).trigger('click');
});
 
$( '#mapTypeId' ).change( function () {
var self = $(this);
TypeIdChange( self.val() );
});
 
google.maps.event.addDomListener( window, 'load', initialize );

That’s It. Now you have successfully created JavaScript Google Map Marker With CSS. In other words, A Custom API Based Map Controls Like add Marker, Zoom In & Out, etc.

Thanks For Visiting, Keep Visiting.

Originally published on https://webdevtrick.com