Skip to content

Commit bd29013

Browse files
Merge pull request #31 from MicheleBertoli/unmounted
does not call the callback on unmounted components
2 parents 629b6e6 + 2f6c7a0 commit bd29013

File tree

8 files changed

+101
-20
lines changed

8 files changed

+101
-20
lines changed

Diff for: dist/components/__tests__/gmaps-test.js

+26
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,30 @@ describe('Gmaps', function () {
152152
expect(parent.refs.gmaps.getMap().setOptions).toBeCalled();
153153
});
154154
});
155+
156+
describe('unmounted', function () {
157+
158+
beforeEach(function () {
159+
GoogleMaps.fireCallbacks = jest.genMockFunction();
160+
});
161+
162+
it('does not fire the callback (unloaded)', function () {
163+
var gmaps = TestUtils.renderIntoDocument(React.createElement(Gmaps, null));
164+
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(gmaps).parentNode);
165+
expect(GoogleMaps.fireCallbacks).not.toBeCalled();
166+
});
167+
168+
it('does not fire the callback (loaded)', function () {
169+
window.google = {
170+
maps: {
171+
event: {
172+
removeListener: jest.genMockFunction()
173+
}
174+
}
175+
};
176+
var gmaps = TestUtils.renderIntoDocument(React.createElement(Gmaps, null));
177+
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(gmaps).parentNode);
178+
expect(GoogleMaps.fireCallbacks).not.toBeCalled();
179+
});
180+
});
155181
});

Diff for: dist/components/gmaps.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,13 @@ var Gmaps = _react2['default'].createClass({
5050
},
5151

5252
componentDidMount: function componentDidMount() {
53-
_utilsGoogleMaps2['default'].load(this.props.params, this.mapsCallback);
53+
this.setState({
54+
callbackIndex: _utilsGoogleMaps2['default'].load(this.props.params, this.mapsCallback)
55+
});
5456
},
5557

5658
componentWillUnmount: function componentWillUnmount() {
59+
_utilsGoogleMaps2['default'].removeCallback(this.state.callbackIndex);
5760
this.removeListeners();
5861
},
5962

@@ -83,7 +86,7 @@ var Gmaps = _react2['default'].createClass({
8386
isMapCreated: true
8487
});
8588
if (this.props.onMapCreated) {
86-
this.props.onMapCreated(this.map, google.maps);
89+
this.props.onMapCreated(this.map);
8790
}
8891
},
8992

Diff for: dist/mixins/listener.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ var Listener = {
1919
},
2020

2121
removeListeners: function removeListeners() {
22-
this.listeners.forEach(function (listener) {
23-
google.maps.event.removeListener(listener);
24-
});
22+
if (window.google) {
23+
this.listeners.forEach(function (listener) {
24+
google.maps.event.removeListener(listener);
25+
});
26+
}
2527
}
2628

2729
};

Diff for: dist/utils/google-maps.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ exports['default'] = {
1717
appended: false,
1818

1919
load: function load(params, callback) {
20-
if (!window.google) {
21-
this.callbacks.push(callback);
20+
var index = this.callbacks.push(callback);
21+
if (window.google) {
22+
setTimeout(this.fireCallbacks.bind(this));
23+
} else {
2224
if (!this.appended) {
2325
window.mapsCallback = this.mapsCallback.bind(this);
2426
this.appendScript(params);
2527
}
26-
} else {
27-
setTimeout(callback);
2828
}
29+
return index;
2930
},
3031

3132
getSrc: function getSrc(params) {
@@ -44,11 +45,19 @@ exports['default'] = {
4445
},
4546

4647
mapsCallback: function mapsCallback() {
47-
window.mapsCallback = undefined;;
48+
window.mapsCallback = undefined;
49+
this.fireCallbacks();
50+
},
51+
52+
fireCallbacks: function fireCallbacks() {
4853
this.callbacks.forEach(function (callback) {
4954
return callback();
5055
});
5156
this.callbacks = [];
57+
},
58+
59+
removeCallback: function removeCallback(index) {
60+
this.callbacks.splice(index - 1, 1);
5261
}
5362

5463
};

Diff for: src/components/__tests__/gmaps-test.js

+27
Original file line numberDiff line numberDiff line change
@@ -148,4 +148,31 @@ describe('Gmaps', () => {
148148

149149
});
150150

151+
describe('unmounted', () => {
152+
153+
beforeEach(() => {
154+
GoogleMaps.fireCallbacks = jest.genMockFunction();
155+
});
156+
157+
it('does not fire the callback (unloaded)', () => {
158+
const gmaps = TestUtils.renderIntoDocument(<Gmaps />);
159+
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(gmaps).parentNode);
160+
expect(GoogleMaps.fireCallbacks).not.toBeCalled();
161+
});
162+
163+
it('does not fire the callback (loaded)', () => {
164+
window.google = {
165+
maps: {
166+
event: {
167+
removeListener: jest.genMockFunction()
168+
}
169+
}
170+
};
171+
const gmaps = TestUtils.renderIntoDocument(<Gmaps />);
172+
ReactDOM.unmountComponentAtNode(ReactDOM.findDOMNode(gmaps).parentNode);
173+
expect(GoogleMaps.fireCallbacks).not.toBeCalled();
174+
});
175+
176+
});
177+
151178
});

Diff for: src/components/gmaps.js

+5-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@ const Gmaps = React.createClass({
1919
},
2020

2121
componentDidMount() {
22-
GoogleMaps.load(this.props.params, this.mapsCallback);
22+
this.setState({
23+
callbackIndex: GoogleMaps.load(this.props.params, this.mapsCallback)
24+
});
2325
},
2426

2527
componentWillUnmount() {
28+
GoogleMaps.removeCallback(this.state.callbackIndex);
2629
this.removeListeners();
2730
},
2831

@@ -54,7 +57,7 @@ const Gmaps = React.createClass({
5457
isMapCreated: true
5558
});
5659
if (this.props.onMapCreated) {
57-
this.props.onMapCreated(this.map, google.maps);
60+
this.props.onMapCreated(this.map);
5861
}
5962
},
6063

Diff for: src/mixins/listener.js

+5-3
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ const Listener = {
1414
},
1515

1616
removeListeners() {
17-
this.listeners.forEach((listener) => {
18-
google.maps.event.removeListener(listener);
19-
});
17+
if (window.google) {
18+
this.listeners.forEach((listener) => {
19+
google.maps.event.removeListener(listener);
20+
});
21+
}
2022
}
2123

2224
};

Diff for: src/utils/google-maps.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,16 @@ export default {
77
appended: false,
88

99
load(params, callback) {
10-
if (!window.google) {
11-
this.callbacks.push(callback);
10+
const index = this.callbacks.push(callback);
11+
if (window.google) {
12+
setTimeout(this.fireCallbacks.bind(this));
13+
} else {
1214
if (!this.appended) {
1315
window.mapsCallback = this.mapsCallback.bind(this);
1416
this.appendScript(params);
1517
}
16-
} else {
17-
setTimeout(callback);
1818
}
19+
return index;
1920
},
2021

2122
getSrc(params) {
@@ -34,9 +35,17 @@ export default {
3435
},
3536

3637
mapsCallback() {
37-
window.mapsCallback = undefined;;
38+
window.mapsCallback = undefined;
39+
this.fireCallbacks();
40+
},
41+
42+
fireCallbacks() {
3843
this.callbacks.forEach(callback => callback());
3944
this.callbacks = [];
45+
},
46+
47+
removeCallback(index) {
48+
this.callbacks.splice(index - 1, 1);
4049
}
4150

4251
};

0 commit comments

Comments
 (0)