diff --git a/STYLE.md b/STYLE.md
index 4017c5bff9fb..ff6e2c0ae530 100644
--- a/STYLE.md
+++ b/STYLE.md
@@ -175,6 +175,23 @@ Empty functions (noop) should be declare as arrow functions with no whitespace i
}
```
+## Accessing Object Properties and Default Values
+
+Use `_.get()` to safely access object properties and `||` to short circuit null or undefined values that are not guaranteed to exist in a consistent way throughout the codebase. In the rare case that you want to consider a falsy value as usable and the `||` operator prevents this then be explicit about this in your code and check for the type using an underscore method e.g. `_.isBoolean(value)` or `_.isEqual(0)`.
+
+ ```javascript
+ // Bad
+ const value = somePossiblyNullThing ?? 'default';
+ // Good
+ const value = somePossiblyNullThing || 'default';
+ // Bad
+ const value = someObject.possiblyUndefinedProperty?.nestedProperty || 'default';
+ // Bad
+ const value = (someObject && someObject.possiblyUndefinedProperty && someObject.possiblyUndefinedProperty.nestedProperty) || 'default';
+ // Good
+ const value = _.get(someObject, 'possiblyUndefinedProperty.nestedProperty', 'default');
+ ```
+
## JSDocs
- Avoid docs that don't add any additional information.
- Always document parameters and return values.
@@ -292,7 +309,8 @@ So, if a new language feature isn't something we have agreed to support it's off
Here are a couple of things we would ask that you *avoid* to help maintain consistency in our codebase:
- **Async/Await** - Use the native `Promise` instead
-- **Optional Chaining** - Use `lodash/get` to fetch a nested value instead
+- **Optional Chaining** - Use `_.get()` to fetch a nested value instead
+- **Null Coalescing Operator** - Use `_.get()` or `||` to set a default value for a possibly `undefined` or `null` variable
# React Coding Standards
diff --git a/src/components/AddressSearch.js b/src/components/AddressSearch.js
index 4f4dc581a886..6de28f19de4a 100644
--- a/src/components/AddressSearch.js
+++ b/src/components/AddressSearch.js
@@ -36,7 +36,11 @@ const defaultProps = {
const AddressSearch = (props) => {
const googlePlacesRef = useRef();
useEffect(() => {
- googlePlacesRef.current?.setAddressText(props.value);
+ if (!googlePlacesRef.current) {
+ return;
+ }
+
+ googlePlacesRef.current.setAddressText(props.value);
}, []);
// eslint-disable-next-line
diff --git a/src/libs/Network.js b/src/libs/Network.js
index a781595089c6..01592b51f381 100644
--- a/src/libs/Network.js
+++ b/src/libs/Network.js
@@ -189,7 +189,7 @@ function processNetworkRequestQueue() {
}
const requestData = queuedRequest.data;
- const requestEmail = requestData.email ?? '';
+ const requestEmail = lodashGet(requestData, 'email', '');
// If we haven't passed an email in the request data, set it to the current user's email
if (email && _.isEmpty(requestEmail)) {
diff --git a/src/libs/actions/IOU.js b/src/libs/actions/IOU.js
index b64e348c7122..29e8b68227c6 100644
--- a/src/libs/actions/IOU.js
+++ b/src/libs/actions/IOU.js
@@ -85,7 +85,8 @@ function createIOUTransaction(params) {
.then((data) => {
getIOUReportsForNewTransaction([data]);
Navigation.navigate(ROUTES.getReportRoute(data.chatReportID));
- })?.catch((error) => {
+ })
+ .catch((error) => {
Onyx.merge(ONYXKEYS.IOU, {
loading: false,
creatingIOUTransaction: false,
@@ -134,7 +135,8 @@ function createIOUSplit(params) {
}
getIOUReportsForNewTransaction(reportParams);
Navigation.navigate(ROUTES.getReportRoute(chatReportID));
- })?.catch((error) => {
+ })
+ .catch((error) => {
Onyx.merge(ONYXKEYS.IOU, {
loading: false,
creatingIOUTransaction: false,
diff --git a/src/libs/fileDownload/index.js b/src/libs/fileDownload/index.js
index aaddeee433ed..dea9353140a2 100644
--- a/src/libs/fileDownload/index.js
+++ b/src/libs/fileDownload/index.js
@@ -23,7 +23,7 @@ export default function fileDownload(url, fileName) {
link.style.display = 'none';
link.setAttribute(
'download',
- fileName ?? getAttachmentName(url), // generating the file name
+ fileName || getAttachmentName(url), // generating the file name
);
// Append to html link element page
diff --git a/src/libs/fileDownload/index.native.js b/src/libs/fileDownload/index.native.js
index 064738142414..60c6dfd66234 100644
--- a/src/libs/fileDownload/index.native.js
+++ b/src/libs/fileDownload/index.native.js
@@ -60,7 +60,7 @@ function handleDownload(url, fileName) {
// android files will download to Download directory
// ios files will download to documents directory
const path = getPlatform() === 'android' ? dirs.DownloadDir : dirs.DocumentDir;
- const attachmentName = fileName ?? getAttachmentName(url);
+ const attachmentName = fileName || getAttachmentName(url);
// fetching the attachment
const fetchedAttachment = RNFetchBlob.config({
@@ -75,18 +75,20 @@ function handleDownload(url, fileName) {
// resolving the fetched attachment
fetchedAttachment.then((attachment) => {
- if (attachment?.info()) {
- showAlert({
- title: 'Downloaded!',
- message: 'Attachment successfully downloaded',
- options: [
- {
- text: 'OK',
- style: 'cancel',
- },
- ],
- });
+ if (!attachment || !attachment.info()) {
+ return;
}
+
+ showAlert({
+ title: 'Downloaded!',
+ message: 'Attachment successfully downloaded',
+ options: [
+ {
+ text: 'OK',
+ style: 'cancel',
+ },
+ ],
+ });
}).catch(() => {
showAlert({
title: 'Attachment Error',
diff --git a/src/pages/NewChatPage.js b/src/pages/NewChatPage.js
index d06a86612541..0061cda49140 100755
--- a/src/pages/NewChatPage.js
+++ b/src/pages/NewChatPage.js
@@ -1,3 +1,4 @@
+import lodashGet from 'lodash/get';
import _ from 'underscore';
import React, {Component} from 'react';
import {View} from 'react-native';
@@ -263,7 +264,7 @@ class NewChatPage extends Component {
forceTextUnreadStyle
/>
{!this.props.isGroupChat && }
- {this.props.isGroupChat && this.state.selectedOptions?.length > 0 && (
+ {this.props.isGroupChat && lodashGet(this.state, 'selectedOptions', []).length > 0 && (