Skip to main content

· 3 min read
Mahesh Muttinti

Steps to Integrate Sentry into the react-native application

Sentry Integration in Turbo Repo

  1. Go to your apps directory which contains all of your apps such as web, mobile, or any other kind of applications you've added to the apps directory.

  2. As you can see, there is a folder called apps/mobile which is a react-native application

  3. I switched to the apps/mobile folder in where I was trying to install the @sentry/react-native SDK into my react native application.

  4. For that I follow the below steps: (macOS - MacBook Air)

    • 4.1. I opened the terminal in my mac (You can use any other terminals you want or go with the vscode terminal)
    • 4.2. Type the cd apps/mobile command in the terminal and click on the enter/return button
    • 4.3. Type the yarn add @sentry/react-native command in the terminal and click on the enter/return button
      • 4.3.1. If you are using the npm package installer, use the npm install --save @sentry/react-native command (but in this repo, it won't work because it is a turbo repo and uses the yarn)
      • For more info, check the Sentry official documentation: "https://docs.sentry.io/platforms/react-native/"
    • 4.4. After the installation was successful, I put the below code in apps/mobile/mobile-screens/index.js
    import {AppRegistry} from 'react-native';
    import App from './mobile-screens';
    import {name as appName} from './app.json';
    import {Provider} from 'react-redux';
    import {mobileStore} from 'store';
    import React from 'react'
    import Config from 'react-native-config';

    // Sentry Code: import & initiate sentry in the App
    import * as Sentry from "@sentry/react-native";
    Sentry.init({
    dsn: Config.SENTRY_DSN, // put SENTRY_DSN env variable in .env, otherwise it fails
    });
    // above App component
    const App = () => {
    ....other code
    }

    // Sentry Code: wrap the App component with a sentry `wrap` HOC function
    export default Sentry.wrap(App);
    • 4.5. Make changes in apps/mobile/index.js with the following code
    import { AppRegistry } from "react-native";
    import App from "./mobile-screens";
    import { name as appName } from "./app.json";
    import { Provider } from "react-redux";
    import { mobileStore } from "store";
    import React from "react";
    // Sentry Code: Import sentry
    import * as Sentry from "@sentry/react-native";

    const MobileApp = () => {
    return (
    // Sentry Code: Wrap the App with "Sentry.TouchEventBoundary"
    <Sentry.TouchEventBoundary>
    <Provider store={mobileStore}>
    <App />
    </Provider>
    </Sentry.TouchEventBoundary>
    );
    };

    AppRegistry.registerComponent(appName, () => MobileApp);

How to use?

const init = async () => {
try {
// error will come because of the comment in the below code
// let tokenFromStorage = await AsyncStorage.getItem('@access_token');

if (tokenFromStorage !== null) {
dispatch(setTokens(JSON.parse(tokenFromStorage)));
let userProfile = await getUser();
if (userProfile) {
dispatch(setUser(userProfile));
}
}
} catch (error) {
// this will execute and will be shown in the Sentry dashboard
Sentry.captureException(error);
}
};

· 5 min read
Mahesh Muttinti

Definition

Custom Hook is a JavaScript function which we create by ourselves, when we want to share logic between other JavaScript functions.

It allows you to reuse some piece of code in several parts of your app.

Useful points

  • The main reason to write a custom hook is for code reusability.
  • For example, instead of writing the same code across multiple components that use the same common stateful logic (say a “setState” or localStorage logic), you can put that code inside a custom hook and reuse it.
  • Custom Hooks are functions. Usually, they start with the word “use” (important convention).
  • Custom Hooks allow us to access the React ecosystem in terms of hooks, which means we have access to all the known hooks like useState, useMemo, useEffect, etc.
  • This mechanism enables the separation of logic and view.

Rules of custom hooks

*Note: The same rules of react hooks will be applicable to the custom hooks.

1. Only Call Hooks at the Top Level

Always use Hooks at the top level of your React function. By following this rule, you ensure that Hooks are called in the same order each time a component renders. That's what allows React to correctly preserve the state of Hooks between multiple useState and useEffect calls.

2. Only Call Custom hooks from React Functions

Don't call custom hooks from regular Javascript functions. Instead, you can

  • ✅ Call Custom hooks from React function components
  • ✅ Call Custom hooks from other Custom hooks

3. Don't call custom hooks conditionally

  • If you want to run an effect conditionally, we can put that condition inside our Custom hook

4. Don't call custom hooks in loops

  • If you want to run an effect without leading bugs, we can put that loops inside our Custom hook

Hooks are better than classes

  • Hooks allow you to use local state and other React features without writing a class.
  • Hooks are special functions that let you “hook onto” React state and lifecycle features inside function components.

Example

useEventListener

  • If you find yourself adding a lot of event listeners using useEffect you might consider moving that logic to a custom hook.
  • In the recipe below we create a useEventListener hook that handles checking if addEventListener is supported, adding the event listener, and removal on cleanup.

1. Create useEventListener.js file

import { useEffect, useRef } from "react";

export default function useEventListener(eventName, handler, element = window) {
// create a ref that store handler
const savedHandler = useRef(null);

// update ref.current value if handler changes
// this allows our effect below to always get latest handler
// without us needing to pass it in effect dependencies array
// and potentially cause effect to re-run every render
useEffect(() => {
savedHandler.current = handler;
}, [handler]);

useEffect(() => {
// make sure element support addEventListener
const isSupported = element && element.addEventListener;
if (!isSupported) return;

// create event listener that calls handler function stored in ref
const eventListener = (event) => savedHandler?.current(event);

// add event listener to element
element.addEventListener(eventName, eventListener);

// remove event listener on cleanup
return () => {
element.removeEventListener(eventName, eventListener);
};
}, [eventName, element]);
}

2. Create App.js file

  • Import useEventListener in App.js file
import React, { useState, useEffect, useRef, useCallback } from "react";
import useEventListener from "./useEventListener";

export default function App() {
const [coords, setCoords] = useState({ x: 0, y: 0 });
const [targetElement, setTargetElement] = useState(null);

const buttonRef = useRef(null);
const headingRef = useRef(null);

// event utilizing useCallback, so that reference never changes
const getCoordinatesOfWindow = useCallback((event) => {
const { clientX, clientY } = event;
// update coordinates
setCoords({ x: clientX, y: clientY });
});

// event utilizing useCallback, so that reference never changes
const getClickedTargetElementTagName = useCallback((event) => {
const { currentTarget } = event;
// update element tag name
setTargetElement(currentTarget.tagName);
});

// this hook is called when your mouse point is changing and give the coordinates of the mouse pointer
// further we are showing the mouse pointer coordinates in UI
useEventListener("mousemove", getCoordinatesOfWindow);

// this hook is called when you click on <button></button> and give the tag name of the button element
// further we are showing in the UI
useEventListener("click", getClickedTargetElementTagName, buttonRef?.current);

// this hook is called when you click on <h1></h1> and give the tag name of the h1 element
// further we are showing in the UI
useEventListener("click", getClickedTargetElementTagName, headingRef?.current);

return (
<div>

<h1>
The mouse coordinates ({coords.x}, {coords.y})
</h1>

<button ref={buttonRef}>Button</button>

<h1 style={{ cursor: "pointer" }} ref={headingRef}>
Heading
</h1>

<h2>You clicked the {targetElement}</h2>

</div>
);
}

Conclusion

I hope this post aids you in better understanding the custom hooks, and will allow you to creating custom hook. If it has been useful to you, please share and spread the word.

Edit on StackBlitz ⚡️ or check the github repo link

· 2 min read
Rajesh Nautiyal

Sometime you might need the list of users from AWS cognito userpool, so lets discuss how to do it? so first things is how do we check users in cognito userpool?

You can get the list of all users with listUsers function of CognitoIdentityServiceProvider

const AWS = require("aws-sdk");


function getCognitoUsers(){
var params = {
UserPoolId: Aws_User_Pool_Id,
};

var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();

return cognitoidentityserviceprovider
.listUsers(params)
.promise()
.then(async (response) => {
return response.Users
})
.catch((error) => {
console.log("cognito error", error);
});
}

But listUsers function have some limitations it gives only 60 users in response. But good thing is that it gives PaginationToken with the response and with that pagination token you can get next 60 users from cognito userool.

So to get the all users from cognito userpool, you have to call listUsers function with PaginationToken in params. Here an example how i did it with recursive function, to get all the users from cognito userpool:

const AWS = require("aws-sdk");

// let users = [];
async function getAllCognitoUsers(paginationToken = ""){
var params = {
UserPoolId: Aws_User_Pool_Id,
};

if (paginationToken !== "") {
params.PaginationToken = paginationToken;
}

var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();

return cognitoidentityserviceprovider
.listUsers(params)
.promise()
.then(async (response) => {
if (response.Users.length < 60) {
users.push(response.Users)
} else {
users.push(response.Users);
await getAllCognitoUsers(response.PaginationToken);
}
})
.catch((error) => {
console.log("cognito error", error);
});
}

· One min read
Shubham Joshi

For Kubernetes Version 1.20

  • create a file called cronjob.yml.
  • Paste the below script:
apiVersion: batch/v1beta1 // for kubernetes-v1.20
kind: CronJob
metadata:
name: nemo-be-cron
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 0 // to delete success history
failedJobsHistoryLimit: 1 // to keep failure history
jobTemplate:
spec:
template:
spec:
containers:
- name: nemo-be-cron
image: CONTAINER_IMAGE
imagePullPolicy: Always
command: ["sh", "-c", "node ./testCommand.js"]
restartPolicy: OnFailure
  • Add changes to the Post script section of Buildspec.yml