Quantcast
Channel: Active questions tagged react-native+typescript - Stack Overflow

Tab Bar Icons not vertically centered React Native Navigation

$
0
0

When testing my react native app (with expo) through the expo go IOS app the icons are not vertically centered, however when testing on web they are vertically centered. I have tried giving each icon a parent div and centering it vertically, giving it a TabBarIconStyle of textAlignVertical: center, and textAlign: center, everything I can think of to vertically align these icons.

My Navigator:

<TabNav.Navigator screenOptions={TabNavOptions}><TabNav.Screen                    name="Home"                    component={HomeScreen}                    options={{                        tabBarIconStyle: { textAlignVertical: "center", textAlign: "center" },                        tabBarIcon: ({ color, size }) => (<View style={{}}><Ionicons name="home" color={color} size={size} style={{ textAlignVertical: "center" }} /></View>                        ),                    }}                /><TabNav.Screen name="Workouts" component={HomeScreen} options={{ tabBarIcon: ({ color, size }) => <Ionicons name="barbell" color={color} size={size} /> }} /><TabNav.Screen name="Exercises" component={HomeScreen} options={{ tabBarIcon: ({ color, size }) => <Ionicons name="bicycle" color={color} size={size} /> }} /></TabNav.Navigator>

My screen options for the Navigator:

const TabNavOptions: BottomTabNavigationOptions = {        tabBarShowLabel: false,        tabBarActiveTintColor: "#4B7079",        tabBarInactiveTintColor: "#FFFFFF",        tabBarStyle: { width: "90%", height: 60, position: "absolute", left: "5%", bottom: 30, borderRadius: 100, borderTopWidth: 0, backgroundColor: "#75B1BC" },    };

This is what it looks like on web (and what it should look like)

enter image description here

This is what it looks like on expo go

enter image description here


expo-router Not Navigating to Route Based on Session State, router.push Fails on Sign Out

$
0
0

I'm working on a React Native project using expo-router, and I'm having an issue with conditional routing based on the session state. I want to navigate to a login screen (auth.tsx) if there's no active session, or to a tab-based screen ((tabs)/index.tsx) if the user is logged in.

Problem:

  • The app always seems to navigate to the index.tsx file, even though I'm using expo-router with conditional routing based on session state.
  • When I check the session state, it’s correctly logged, but the route isn't behaving as expected.
  • Additionally, when I try to sign out using router.push('app/auth.tsx'), the navigation doesn't work, and it returns an error that the route could not be found.

Please help me out.

    // app/_layout.tsx (this is the root layout)    import React, { useEffect } from 'react';    import { View, Text } from 'react-native';    import { Stack } from 'expo-router';    import { useAuth } from '../context/AuthContext';    function AppContent() {      const { session, isLoading } = useAuth();      if (isLoading) {        return (<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}><Text>Loading...</Text></View>        );      }      return (<Stack screenOptions={{ headerShown: false }}>          {!session || !session.user ? ( // this does not work            // Navigate to auth if session is null, undefined, or invalid<Stack.Screen name="auth" options={{ headerShown: false }} />          ) : (            // Navigate to (tabs) if session and user are valid<Stack.Screen name="(tabs)" options={{ headerShown: false }} />          )}</Stack>      );    }    export default function App() {      return (<AuthProvider><AppContent /></AuthProvider>      );    }

I've made sure that the file structure matches expo-router conventions:

    /app├── auth.tsx          // Login screen├── _layout.tsx       // Root layout└── (tabs)└── index.tsx     // Tab-based screen└── _layout.tsx   // Tab-based layout

Sign Out Buttons:

<TouchableOpacity onPress={async () => {        try {            const { error } = await supabase.auth.signOut();            if (error) {                    console.error('Error signing out:', error.message);                } else {                    console.log('Successfully logged out');                    // Sign out the user                    await router.push('../../app/auth.tsx');                  }             } catch (err) {                 console.error('Unexpected error during sign out:', err);                 }         }}><Text style={[styles.drawerItem, styles.logout]}>Logout</Text></TouchableOpacity>
<Button        title="Sign Out"        onPress={async () => {            await supabase.auth.signOut(); // Sign out the user            router.push('/app/Auth.tsx'); // Navigate to the Auth page        }}        color="#34d399"    />

Type error when using styled-components/native

$
0
0

I'm trying to configure the styled-components for my application but I'm having a problem with the types when using the 'styled-components/native'. The type display error but it works.

tsconfig.json

{"extends": "@react-native/typescript-config/tsconfig.json","compilerOptions": {"jsx": "react","types": ["styled-components-react-native","node",    ],"plugins": [      {"name": "@styled/typescript-styled-plugin","lint": {"validProperties": ["shadow-color","shadow-opacity","shadow-offset","shadow-radius","padding-horizontal","padding-vertical","margin-vertical","margin-horizontal","tint-color","aspect-ratio","elevation"          ]        }      }    ],    ...  }}

theme.ts

import pallete from './pallete';export const theme = {  colors: { ...pallete },  font: {},};export type ThemeType = typeof theme;

styled.d.ts

import 'styled-components/native';import type { ThemeType } from '../theme';declare module 'styled-components/native' {  export interface DefaultTheme extends ThemeType {}}

App.tsx

import React from 'react';import { ThemeProvider } from 'styled-components';import { theme } from '@src/common/theme';function App(): JSX.Element {  return (<ThemeProvider theme={theme}>      ...</ThemeProvider>  );}

As you can see there is no types coming from the props.

enter image description here

But if I change the import and use html tags it works.enter image description here

React Native Aliases TypeScript after adding metro.config.js

$
0
0

I have a new TypeScript project, and I'm working on adding aliases. I had set up bable.config.js and tsconfig.json, and everything was working; however, in order to resolve an issue with react-native-svg-transformer, I had to add a metro.config.js file. After the addition of this file, my aliases are throwing a type error. The project builds and runs, but I'd like to resolve the errors.

bable.config.js

module.exports = function (api) {  api.cache(true);  return {    presets: ["babel-preset-expo"],    plugins: [      ['module-resolver',        {          root: ['.'],          extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],          alias: {'@assets': './assets/*','@components': './src/components/*','@screens': './src/screens/*','@navigation': './src/navigation/*','@constants': './src/constants/*',          },        },      ],    ]  };};

tsconfig.json

{"extends": "expo/tsconfig.base","include": ["src/components","src/custom.d.ts"  ],"compilerOptions": {"strict": true,"baseUrl": "./","rootDir": ".","paths": {"*": ["./src/*"],"@assets/*": ["./assets"],"@components/*": ["./src/components"],"@screens/*": ["./src/screens"],"@navigation/*": ["./src/navigation"],"@constants/*": ["./src/constants"],    }  }}

and metro.config.js

const { getDefaultConfig: getDefaultExpoConfig } = require("@expo/metro-config")metroConfig = (() => {  const config = getDefaultExpoConfig(__dirname)  const { transformer, resolver } = config  config.transformer = {    ...transformer,    babelTransformerPath: require.resolve("react-native-svg-transformer"),  }  config.resolver = {    ...resolver,    assetExts: resolver.assetExts.filter((ext) => ext !== "svg"),    sourceExts: [...resolver.sourceExts, "svg"],  }  return config})()module.exports = metroConfig

I also have a git repository for the project here working out of the feature/adding-navigation branch

Passing fetched data as props in typescript react-native

$
0
0

I'm trying to convert to typescript and I'm having trouble declaring types and I want to pass necessary fields only. I encountered this error:

Type 'Document' is not assignable to type 'string'.ts(2322)VideoCard.tsx(18, 3): The expected type comes from property 'video' which is declared here on type 'IntrinsicAttributes & Video'

I'm using Appwrite and react native

Here is my FlatList from react native

<FlatList        data={posts}        keyExtractor={(item: any) => item.$id}        renderItem={({ item }) => {          console.log(item);          return  <VideoCard video={item} />;        }}      ..// so on />

Here is my VideoCard Component:

interface Creator {  username: string;  avatar: string;}interface Video extends Document {  title: string;  thumbnail: string;  video: string;  creator: Creator;}const VideoCard: React.FC<Video> = (video) => {  return (<View><Text className="text-white text-3xl">{video.title}</Text></View>  );};export default VideoCard;

So for context, this is the value of console.log(item) I replaced the ids

{"title": "Get inspired to code","thumbnail": "https://i.ibb.co/tJBcX20/Appwrite-video.png","prompt": "Create a motivating AI driven video aimed at inspiring coding enthusiasts with simple language","video": "https://player.vimeo.com/video/123abcd?h=897cd5e781","$id": "123abcd","$createdAt": "2025-01-22T04:54:59.596+00:00","$updatedAt": "2025-01-22T04:54:59.596+00:00","$permissions": [],"creator": {"username": "jam","email": "jam@gmail.com","avatar": "https://cloud.appwrite.io/v1/avatars/initials?name=jam&project=123abcd","accountId": "123abcd","$id": "123abcd","$createdAt": "2025-01-21T18:30:14.390+00:00","$updatedAt": "2025-01-21T18:30:14.390+00:00","$permissions": ["read(\"user:123abcd\")","update(\"user:123abcd\")","delete(\"user:123abcd\")"    ],"$databaseId": "123abcd","$collectionId": "123abcd"},"$databaseId": "123abcd","$collectionId": "123abcd"

}

How to Avoid Repeatedly Calling Hooks for Theme and Responsive Styles in React Native Components?

$
0
0

What I want to achieve: A performant react native theme manager/changer.

Styles should be usable like: <View style={styles.screen}> where styles comes from a styles.ts file where I define my style. There, I should have access to theme color (ex: Dark/Light) and dynamic dimensions (width, height), meaning that if I change to landscape and back, the styling updates accordingly.

Currently, I have this implementation. However, in every component I have to call this hook with my specific style const styles = useStyles();. I'd like to avoid that (or hide this) and simply only have to import them before using them, so I won't have to call such a hook for every single style I import in every component.

App.tsx

import { NavigationContainer, DefaultTheme } from '@react-navigation/native';import { createStackNavigator, StackScreenProps } from '@react-navigation/stack';import { Button, View, Text, TouchableOpacity } from 'react-native';import { useThemeStore, colors } from './themeStore';import { useStyles } from './styles';type RootStackParamList = {  Home: undefined;  Settings: undefined;};const Stack = createStackNavigator<RootStackParamList>();function HomeScreen({ navigation }: StackScreenProps<RootStackParamList, 'Home'>) {  const styles = useStyles();  const toggleTheme = useThemeStore(state => state.toggleTheme);  return (<View style={styles.screen}><View style={[styles.container, { marginTop: 40 }]}><Text style={styles.header}>Home Screen</Text><Text style={styles.text}>Current theme settings</Text></View><View style={styles.container}><Button title="Toggle Theme" onPress={toggleTheme} /><TouchableOpacity          style={[styles.button, { marginTop: 16 }]}          onPress={() => navigation.navigate('Settings')}><Text style={styles.buttonText}>Go to Settings</Text></TouchableOpacity></View></View>  );}function SettingsScreen({ navigation }: StackScreenProps<RootStackParamList, 'Settings'>) {  const styles = useStyles();  const theme = useThemeStore(state => state.theme);  return (<View style={styles.screen}><View style={styles.container}><Text style={styles.header}>Settings Screen</Text><Text style={styles.text}>Current Theme: {theme.toUpperCase()}</Text><TouchableOpacity          style={[styles.button, { marginTop: 16 }]}          onPress={() => navigation.goBack()}><Text style={styles.buttonText}>Go Back</Text></TouchableOpacity></View></View>  );}export default function App() {  const theme = useThemeStore(state => state.theme);  const navigationTheme = {    ...DefaultTheme,    dark: theme === 'dark',    colors: {      ...DefaultTheme.colors,      ...colors[theme],    },  };  return (<NavigationContainer theme={navigationTheme}><Stack.Navigator        screenOptions={{          headerStyle: {            backgroundColor: navigationTheme.colors.card,          },          headerTintColor: navigationTheme.colors.text,        }}><Stack.Screen name="Home" component={HomeScreen} /><Stack.Screen name="Settings" component={SettingsScreen} /></Stack.Navigator></NavigationContainer>  );}

themeStore.ts

import { MMKVLoader } from 'react-native-mmkv-storage';import {create} from 'zustand';import { persist } from 'zustand/middleware';import { storage } from './storage';export const storage = new MMKVLoader()  .withInstanceID('themeStorage')  .initialize();export const colors = {  light: {    primary: '#007AFF',    background: '#FFFFFF',    card: '#FFFFFF',    text: '#000000',    border: '#D3D3D3',    notification: '#FF3B30',  },  dark: {    primary: '#BB86FC',    background: '#121212',    card: '#1E1E1E',    text: '#FFFFFF',    border: '#383838',    notification: '#CF6679',  },};interface ThemeState {  theme: 'light' | 'dark';  toggleTheme: () => void;}export const useThemeStore = create<ThemeState>()(  persist(    (set) => ({      theme: 'light',      toggleTheme: () => set((state) => ({        theme: state.theme === 'light' ? 'dark' : 'light'      })),    }),    {      name: 'theme-storage',      storage: {        getItem: async (name) => {          const value = storage.getString(name);          return value ? JSON.parse(value) : null;        },        setItem: async (name, value) => {          storage.setString(name, JSON.stringify(value));        },        removeItem: async (name) => {          storage.removeItem(name);        },      },    }  ));

styles.ts

import { useThemeStore } from './themeStore';import { useDimensionsStore } from './dimensionsStore';import { StyleSheet } from 'react-native';import { colors } from './themeStore';export const useStyles = () => {  const theme = useThemeStore(state => state.theme);  const { width, height } = useDimensionsStore();  const themeColors = colors[theme];  return StyleSheet.create({    screen: {      flex: 1,      backgroundColor: themeColors.background,      width,      height,    },    container: {      padding: 16,      backgroundColor: themeColors.card,      borderRadius: 8,      margin: 8,    },    text: {      color: themeColors.text,      fontSize: 16,    },    header: {      color: themeColors.primary,      fontSize: 24,      fontWeight: 'bold',    },    button: {      backgroundColor: themeColors.primary,      padding: 12,      borderRadius: 8,      alignItems: 'center',    },    buttonText: {      color: themeColors.background,      fontWeight: 'bold',    },  });};

Axios Returns 401 in React Native App but Works in Node.js with the Same Credentials

$
0
0

I am currently building a CalDAV client library in TypeScript that works fine in a Node.js environment. However, when I use the same library in a React Native app running on an iOS simulator, I get a 401 Unauthorized response from the server, even though I’m using the exact same credentials and code.

Things i tried:

  • I logged the Requests in both environments and compared them to see that they are identical.
  • I already checked for any native specific errors regarding the dependencies.

This is the code of my Client: client.ts

Signal Protocol Issue: Missing Signed PreKey and Session Errors

$
0
0

Please I am having issues implementing signal protocol, like the creation of prekey, registering to server, fetch prekey bundle, and encrypting is not an issue, but decrpting is where the challenges begin.

Here’s the scenario:

  1. Initial Setup:

    • Alice and Bob both register on the server and upload their pre-key bundles.
    • Alice sends the first message to Bob using Bob’s pre-key bundle to encrypt it.
  2. Problem on Bob’s Side (First Issue):

    • Bob receives the encrypted PreKeyWhisperMessage but fails to decrypt it.
    • The following error is thrown:
      [Error: Missing Signed PreKey for PreKeyWhisperMessage]
    • Note: Bob has not sent any message to Alice before this.
  3. Problem on Alice’s Side (Second Issue):

    • After Bob encounters the above error, if Bob then sends a message to Alice, Alice throws this error when trying to decrypt the message:
      [Error: unable to find session for base key BX+cGz/mCJDPm2R4bJ7ggHzaX8gCBLOZN5Z6VZSxs+hO, 33]
    • This error seems to indicate that Alice cannot find a session for the baseKey from Bob.
  4. Observations:

    • On Bob’s device, before encrypting, I can see the baseKey in the cipher object.
    • However, when I inspect the cipher object on Alice’s device after the error occurs, I cannot find the baseKey in the session or storage.
    • Here’s a sample log of the cipher from Alice’s side during decryption:
      {"encryptJob": [Function anonymous], "fillMessageKeys": [Function anonymous], "loadKeysAndRecord": [Function anonymous], ...}
      The baseKey (BX+cGz/mCJDPm2R4bJ7ggHzaX8gCBLOZN5Z6VZSxs+hO) is missing, which seems to align with the error message.
  5. Questions:

    • Why is the "Missing Signed PreKey for PreKeyWhisperMessage" error occurring on Bob’s device for the first message from Alice?
    • Why does Alice then throw the "unable to find session for base key" error when trying to decrypt Bob’s response?
    • Is there a fundamental step I’m missing, such as session setup or pre-key handling, especially when Bob hasn’t sent any message before?

please note: that I am using the modify version of this storage src/test/storage-type.ts but integrated with MMKV for persistence


NativeWind Styles Not Applying to Custom Components

$
0
0

Question Body:

I am building a React Native application and using NativeWind for styling. While styling works as expected on the main screen components, I am encountering a peculiar issue when using NativeWind styles in custom components.

Problem:

When I use NativeWind styles like bg- or border- in my custom components, they don't get applied. However:

  1. The same styles work perfectly fine on the main screen components.
  2. If I use the same tag (used in the custom component) directly on the main screen and apply the bg- or border- styles there, the styles for the custom component also start working correctly.

Here is my code for my Custom Button component button.tsx

import { Text, TouchableOpacity, View } from "react-native";const Button = () => {  return (<TouchableOpacity className="p-2 bg-yellow-400 mt-10 border-2 border-black"><Text className="bg-blue-500">Button</Text></TouchableOpacity>  );};export default Button;

The problem I am facing with this component is that the styles like bg-yellow-400 and border are not loading in my app.

Here is my Main Screen Code.

import { Image, Text, TouchableOpacity, View } from "react-native";import { SafeAreaView } from "react-native-safe-area-context";import Swiper from "react-native-swiper";import { useRef, useState } from "react";import CustomButton from "@/components/customButton";import { onboarding } from "@/constants";import { router } from "expo-router";import Button from "@/components/button";const Welcome = () => {  const swiperRef = useRef(null);  const [activeIndex, setActiveIndex] = useState(0);  const isLastSlide = activeIndex === onboarding.length - 1;  return (<SafeAreaView className="flex h-full items-center justify-between bg-white"><TouchableOpacity        className="w-full flex justify-end items-end p-3 px-5"        onPress={() => {          router.replace("/(auth)/sign-up");        }}><Text className="text-black text-md font-DMSansRegular">Skip</Text></TouchableOpacity><Swiper        ref={swiperRef}        loop={false}        dot={<View className="w-[32px] h-[4px] mx-1 bg-[#E2E8F0] rounded-full" />        }        activeDot={<View className="w-[32px] h-[4px] mx-1 bg-[#0286FF] rounded-full" />        }        onIndexChanged={(index) => setActiveIndex(index)}>        {onboarding.map((item) => (<View key={item.id} className="flex items-center justify-center p-5"><Image              source={item.image}              className="w-full h-[300px]"              resizeMode="contain"            /><View className="flex items-center justify-center w-full mt-10"><Text className="text-black font-bold font-DMSansRegular text-3xl">                {item.title}</Text><Text>{item.description}</Text>             {/* ------------- Custom Button That I am Loading ------------- */}<Button />             {/* ------------- Custom Button That I am Loading ------------- */}</View></View>        ))}</Swiper></SafeAreaView>  );};export default Welcome;

This is the output of my app after loading the custom button, As you can see There is no styling of the button even if I added styling in the button component.

App screen image where custom component styles are not laoding

What I Tried:

  1. I set up NativeWind as per the official documentation with React Native.

  2. Checked for typos or configuration issues in tailwind.config.js but didn't find any problems.
    My tailwind.config.js looks like this.

    /** @type {import('tailwindcss').Config} */module.exports = {  // NOTE: Update this to include the paths to all of your component files.  content: ["./app/**/*.{js,jsx,ts,tsx}"],  presets: [require("nativewind/preset")],  theme: {    extend: {      fontFamily: {        DMSansRegular: ["DMSans-Regular", "sans-serif"],      },    },  },  plugins: [],};
  3. Ensured that my custom components are passing down all the prop properly.

I also tried adding the same code in my custom component directly in my main screen. So here is the new code of my main screen.

import { Image, Text, TouchableOpacity, View } from "react-native";import { SafeAreaView } from "react-native-safe-area-context";import Swiper from "react-native-swiper";import { useRef, useState } from "react";import CustomButton from "@/components/customButton";import { onboarding } from "@/constants";import { router } from "expo-router";import Button from "@/components/button";const Welcome = () => {  const swiperRef = useRef(null);  const [activeIndex, setActiveIndex] = useState(0);  const isLastSlide = activeIndex === onboarding.length - 1;  return (<SafeAreaView className="flex h-full items-center justify-between bg-white"><TouchableOpacity        className="w-full flex justify-end items-end p-3 px-5"        onPress={() => {          router.replace("/(auth)/sign-up");        }}><Text className="text-black text-md font-DMSansRegular">Skip</Text></TouchableOpacity><Swiper        ref={swiperRef}        loop={false}        dot={<View className="w-[32px] h-[4px] mx-1 bg-[#E2E8F0] rounded-full" />        }        activeDot={<View className="w-[32px] h-[4px] mx-1 bg-[#0286FF] rounded-full" />        }        onIndexChanged={(index) => setActiveIndex(index)}>        {onboarding.map((item) => (<View key={item.id} className="flex items-center justify-center p-5"><Image              source={item.image}              className="w-full h-[300px]"              resizeMode="contain"            /><View className="flex items-center justify-center w-full mt-10"><Text className="text-black font-bold font-DMSansRegular text-3xl">                {item.title}</Text><Text>{item.description}</Text>             {/* ------------- Custom Button That I am Loading ------------- */}<Button />             {/* ------------- Custom Button That I am Loading ------------- */}            {/* ---- Added code similar to my custom component ----- */}<TouchableOpacity className="bg-yellow-400 mt-2 p-2"><Text className="bg-blue-500">Button</Text></TouchableOpacity>           {/* ---- Added code similar to my custom component ----- */}</View></View>        ))}</Swiper></SafeAreaView>  );};export default Welcome;

After adding a TouchableOpacity with the same styles as my custom component to the main screen, the styles for the custom component started working.

Here is the image of my app after the custom component started working.

App screen image where custom button loads properly

My Project Dependencies

{  "dependencies": {"@clerk/clerk-expo": "^2.6.15","@clerk/types": "^4.41.2","@expo/vector-icons": "^14.0.2","@react-navigation/bottom-tabs": "^7.0.0","@react-navigation/native": "^7.0.0","expo": "~52.0.20","expo-blur": "~14.0.1","expo-constants": "~17.0.3","expo-font": "~13.0.2","expo-haptics": "~14.0.0","expo-linking": "~7.0.3","expo-router": "^4.0.15","expo-secure-store": "^14.0.0","expo-splash-screen": "~0.29.21","expo-status-bar": "~2.0.0","expo-symbols": "~0.2.0","expo-system-ui": "~4.0.6","expo-web-browser": "~14.0.1","nativewind": "^4.1.23","react": "18.3.1","react-dom": "19.0.0","react-native": "^0.76.6","react-native-gesture-handler": "~2.20.2","react-native-reanimated": "^3.16.6","react-native-safe-area-context": "^5.1.0","react-native-screens": "^4.4.0","react-native-swiper": "^1.6.0","react-native-web": "~0.19.13","react-native-webview": "13.12.5","tailwindcss": "^3.4.17"  },"devDependencies": {"@babel/core": "^7.25.2","@types/jest": "^29.5.12","@types/react": "~18.3.12","@types/react-test-renderer": "^18.3.0","jest": "^29.2.1","jest-expo": "~52.0.2","react-test-renderer": "18.3.1","typescript": "^5.3.3"  },}

So my observation is this

  • Styles like bg-red-500 and border border-black do not apply to CustomComponent.

  • When I add a similar View with the same styles (bg-red-500 border border-black) in MainScreen, the styles for CustomComponent suddenly start working.

My Questions:

  1. Why is this happening, and how can I fix it so that NativeWind styles apply correctly to custom components without needing a similar tag on the main screen?

  2. Is there some dependency or configuration issue I might have overlooked?

Any insights or suggestions would be greatly appreciated! Thanks.

DB.transaction not waiting for Promise.all to resolve and moves to the next then statement

$
0
0

I have the following code in a function

          return Database.createDatabase()          .then((database)=> {            return insertSurvey(parsedData,database)          })          .then((outa)=>{            console.log(outa)          })

The createDatabase enables sqlite promisesThe insertSurvey code is as follows

const insertSurvey =  (surveyObject : any, database) => {  return database.transaction((tx) => {    console.log("BEFORE SURVEY_INSERT_STRING executeSql")    return tx.executeSql(        Database.SURVEY_INSERT_STRING ,        [          surveyObject.troubleShooting,        ]       )       .then(async ()=>{        let arrayOfPromisesForAssetInsertion = []        for(let count = 0 ; count < survey.assets.length; count ++)        {          arrayOfPromisesForAssetInsertion.push(insertAsset(tx,survey.assets[count], survey.surveyId))        }        return Promise.all(arrayOfPromisesForAssetInsertion) // REACHED POINT      })      .then((valuesAfterAssetInsertion)=>{.         console.log(valuesAfterAssetInsertion)  // DOES NOT REACH HERE        let arrayOfIssuesInsertion = survey.assets.map((asset) =>           insertIssues(tx, asset, survey.surveyId)        );        return Promise.all(arrayOfIssuesInsertion)      })      .catch((msg)=>{        console.log("error caught ",msg)      })  })    .then((sur)=>{      // console.log("returning transaction and surveyObject",tx,surveyObject)      return "output". // LINE OUTPUT    })  }function insertAsset(tx, asset, surveyId) {  setLoadingText ( "Assets")  return tx.executeSql(    Database.ASSETS_INSERT_STRING ,    [      asset.completed ?? false    ])  .then((values)=>{      return values  })}

Here when the insertSurvey executes after reaching "return Promise.all(arrayOfPromisesForAssetInsertion)" the code jumps to "return "output" i.e // LINE OUTPUT. The following "console.log(valuesAfterAssetInsertion)" statement is not reached. The point // DOES NOT REACH HERE is not reached. There is no error as even catch is not reached.Why is the DB.transaction not hitting the "console.log(valuesAfterAssetInsertion)" point

The archive did not include a dSYM for the hermes.framework with the UUIDs [some uuid] in react native

$
0
0

i am facing issue when uploading archive file from xcode to apple app store in react native project

The archive did not include a dSYM for the hermes.framework with theUUIDs [B7ABE37E-553E-3465-82BA-50EFAA0CB16C]. Ensure that thearchive's dSYM folder includes a DWARF file for hermes.framework withthe expected UUIDs.

i check on internet but no solution found

below is my podfile

# Transform this into a `node_require` generic function:def node_require(script)  # Resolve script with node to allow for hoisting  require Pod::Executable.execute_command('node', ['-p',"require.resolve('#{script}',      {paths: [process.argv[1]]},    )", __dir__]).stripend# Use it to require both react-native's and this package's scripts:node_require('react-native/scripts/react_native_pods.rb')node_require('react-native-permissions/scripts/setup.rb')platform :ios, '13.4'prepare_react_native_project!flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabledlinkage = ENV['USE_FRAMEWORKS']if linkage != nil  Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green  use_frameworks! :linkage => linkage.to_symendtarget 'UNFApp' do  config = use_native_modules!  flags = get_default_flags()  flags[:hermes_enabled] = true  use_react_native!(    :path => config[:reactNativePath],    :fabric_enabled => flags[:fabric_enabled],    :flipper_configuration => flipper_config,    :app_path => "#{Pod::Config.instance.installation_root}/.."  )  # ⬇️ Add the permissions you need  setup_permissions(['LocationWhenInUse', # Location access when the app is in use'LocationAlways',  ])  pod 'RNVectorIcons', :path => '../node_modules/react-native-vector-icons'  pod 'RNReanimated', :path => '../node_modules/react-native-reanimated'  pod 'GoogleUtilities', :modular_headers => true  pod 'react-native-maps', :path => '../node_modules/react-native-maps'  pod 'react-native-google-maps', :path => '../node_modules/react-native-maps'  target 'UNFAppTests' do    inherit! :complete  end  bitcode_strip_path = `xcrun --find bitcode_strip`.chop!  def strip_bitcode_from_framework(bitcode_strip_path, framework_relative_path)    framework_path = File.join(Dir.pwd, framework_relative_path)    command = "#{bitcode_strip_path} #{framework_path} -r -o #{framework_path}"    puts "Stripping bitcode: #{command}"    system(command)  end  hermes_framework_path = "#{Pod::Config.instance.installation_root}/Pods/hermes-engine/destroot/Library/Frameworks"framework_paths = ["#{hermes_framework_path}/universal/hermes.xcframework/ios-arm64/hermes.framework/hermes","#{hermes_framework_path}/universal/hermes.xcframework/ios-arm64_x86_64-maccatalyst/hermes.framework/hermes"]bitcode_strip_path = `xcrun --find bitcode_strip`.chop!framework_paths.each do |framework_relative_path|  strip_bitcode_from_framework(bitcode_strip_path, framework_relative_path)end  # framework_paths.each do |framework_relative_path|  #   strip_bitcode_from_framework(bitcode_strip_path, framework_relative_path)  # end  post_install do |installer|    react_native_post_install(      installer,      config[:reactNativePath],      :mac_catalyst_enabled => false    )    installer.pods_project.targets.each do |target|      if target.name == 'hermes-engine'        target.build_configurations.each do |config|          config.build_settings['EXCLUDED_ARCHS[sdk=iphonesimulator*]'] = 'arm64'        end      end    end    __apply_Xcode_12_5_M1_post_install_workaround(installer)  endend

below are my react native version

"react": "18.2.0","react-native": "0.72.0",

React native victory chart gives error value undefined

$
0
0

I am using the VictoryNative chart library in my React Native project to render a bar chart based on dynamically calculated data passed via the insights prop. However, when I try to render the chart, I encounter the following error:

typescriptCopyEditError: Exception in HostFunction: Value is undefined, expected a numberWhat I’m trying to do:I am dynamically calculating the earnings for different platforms (youtube, spotify, etc.) based on data passed in insights.I need to plot the earnings on a bar chart for the top 10 platforms.

import {StyleSheet, Text, useWindowDimensions, View} from 'react-native';import React, {useEffect, useState} from 'react';import {  Area,  Bar,  CartesianChart,  Line,  useChartPressState,} from 'victory-native';import {  Circle,  Image,  LinearGradient,  Text as SKText,  useFont,  useImage,  vec,} from '@shopify/react-native-skia';import {abbreviateNumber} from '../../../../common/Common';interface PlatformTotals {  platform: string;  earnings: number;}const PlatformBarChart = ({ insights }: { insights: any }) => {  const font = useFont(require('../../../../../assets/fonts/DMSans-Regular.ttf'), 10);  const { width, height } = useWindowDimensions();  const [platformData, setPlatformsData] = useState<PlatformTotals[]>([]);  useEffect(() => {    if (insights) calculatePlatformTotals(insights);  }, [insights]);  const calculatePlatformTotals = (data: any) => {    const platformTotals: { [platform: string]: number } = {};    // Iterate over each platform in the data    Object.keys(data).forEach(platform => {      if (platform === 'Total Revenue') return;      const platformData = data[platform];      Object.keys(platformData).forEach(year => {        const yearData = platformData[year];        Object.keys(yearData).forEach(month => {          const monthData = yearData[month];          // Accumulate earnings if available          if (monthData && monthData.earnings) {            if (platformTotals[platform]) {              platformTotals[platform] += monthData.earnings;            } else {              platformTotals[platform] = monthData.earnings;            }          }        });      });    });    // Convert and sort the platform totals    const sortedPlatforms = Object.entries(platformTotals)      .map(([platform, earnings]) => ({ platform, earnings }))      .sort((a, b) => b.earnings - a.earnings)      .slice(0, 10); // Get top 10 platforms    setPlatformsData(sortedPlatforms);  };  return (<View ><CartesianChart          xKey={'platform' as never}          padding={5}          yKeys={['earnings'] as never}          domainPadding={{ left: 50, right: 50, top: 0, bottom: 0 }}          frame={{            lineWidth: { top: 0, left: 0, right: 1, bottom: 0 },            lineColor: 'white',          }}          axisOptions={{            font: font,            formatYLabel: (value: any) => `${abbreviateNumber(value, 3)}`,            formatXLabel: (value: any) => ``,            lineWidth: { grid: { x: 0.2, y: 0.2 }, frame: 0 },            lineColor: '#d4d4d8',            labelColor: 'white',            labelOffset: { x: 10, y: 10 },            axisSide: { x: 'bottom', y: 'right' },          }}          data={platformData as any}>          {({ points, chartBounds }: any) => {            return points?.earnings?.map((item: any, index: any) => {              return (<><Bar                    points={[item]}                    chartBounds={chartBounds}                    animate={{ type: 'spring' }}                    color={getColor(item?.xValue)}                    barWidth={20}                    roundedCorners={{                      topLeft: 3,                      topRight: 3,                    }}                  /></>              );            });          }}</CartesianChart></View>  );};```I am using victory-nativeTypeScript icon, indicating that this package has built-in type declarations41.16.0 I am receiving the Error: Exception in HostFunction: Value is undefined, expected a number error when trying to render the chart. The platformData is populated with the calculated earnings values, but it seems like one or more of them might be undefined, causing the error.What I’ve tried:I’ve confirmed that platformData is correctly populated with the expected values.I added checks in the calculatePlatformTotals function to ensure the earnings are valid numbers before adding them to platformTotals.

TouchableOpacity and onPress for Icons

$
0
0

I am trying to use onPress for icons. For this, I thought of using TouchableOpacity but nothing happens when I click on the icon. I don't see any console logs.

I also tried wrapping the icon in an additional View but that doesn't work either.

const criteriaList = ["Nur Frauen","Freunde Zweiten Grades",]export const FilterCriteriaList: React.FunctionComponent = () => {  return (<View style={styles.container}><View style={styles.horizontalLine} />          {criteriaList.map((item: string) => (<View key={item}><View style={styles.criteriaRow}><TouchableOpacity style={styles.iconContainer} onPress={()=>console.log('dhjksds')}><Icon style={styles.icon} name="circle-thin" color="#31C283" size={moderateScale(20)}/></TouchableOpacity><Text style={styles.text}>{item}</Text></View><View style={styles.horizontalLine} /></View>      ))}</View>  );};const styles = StyleSheet.create({  container: {    flex: 1,  },  criteriaRow: {      flexDirection: 'row',      paddingLeft: moderateScale(25),  },  horizontalLine: {    width: '100%',    height: moderateScale(1),    backgroundColor: '#E0E0E0',  },  text: {    paddingLeft: moderateScale(15),    paddingBottom: moderateScale(15),    marginBottom: moderateScale(15),    paddingTop: moderateScale(15),  },  icon: {      paddingTop: moderateScale(12),  },  iconContainer: {      backgroundColor: 'red',  }});

enter image description here

It looks like this and I click in the middle of the circle icon.

What else can I try?

enter image description here

Expo ScrollView stops working when sub directory layout contains a Stack layout

$
0
0

I have the following app file layout

app/   story/     _layout.tsx     index.tsx_layout.tsxindex.tsx

I am not sure why but when I use a Stack layout in one of the sub directories, the ScrollView I use at the top level layout stops working. If I remove the Stack layout (from app/story/_layout.tsx) then the scrolling starts working again.

I tried updating the Stack contentStyle with flex/flexGrow but neither made a difference. Can anyone explain why the scrolling stops when I use Stack navigation?

Also I noticed that the scrolling works in web mode but not on android but I'm guessing this is just because Stacks aren't a thing web view.

File Contents:app/_layout.tsx

import React from "react";import { Slot } from "expo-router";import { ScrollView, StyleSheet } from "react-native";export default () => (<><ScrollView style={styles.scroll} id="ui-scrollview" contentContainerStyle={styles.scrollContainer}><Slot /></ScrollView></>);const styles = StyleSheet.create({    scroll: { flex: 1, height: "100%" },    scrollContainer: { flexGrow: 1 },});

app/index.tsx

import { router } from "expo-router";import React from "react";import { Button } from "react-native";interface IAppIndexProps {}const AppIndex: React.FC<IAppIndexProps> = () => {    return <Button title="Story" onPress={() => router.push("/story")} />;};export default AppIndex;

app/story/_layout.tsx

import { Stack } from "expo-router";export default () => <Stack />; // < ---- this stops scroll view working

app/story/index.tsx

import React from "react";import { Text } from "react-native";interface IStoryIndexProps {}const lorem ="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.";const StoryIndex: React.FC<IStoryIndexProps> = () => {    return (<Text style={{ flex: 1 }}>            //Large data to force scroll            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}            {lorem}</Text>    );};export default StoryIndex;

Example repo here https://github.com/welcometochristown/expo_stack_scroll_issue

How to handle internet disconnection when loading an expo-av video component

$
0
0

I have a simple reactnative component, which has the expo-av video element on it.

I'm having an issue were if the network is disconnected when attempting to play the video and then when the internet connection returns, it does not resume playing the video.

any ideas? some code below (simplified)

export default function VideoView(props: any) {  const {question} = props;  return <Video    videoStyle={{marginHorizontal: 10}}    source={{uri: question.video_url}}    rate={1.0}    volume={1.0}    isMuted={false}    resizeMode={ResizeMode.CONTAIN}    shouldPlay    ref={videoRef}    style={{width: windowWidth, height: windowHeight}}   />}

upload mp3 to server doesn't work in react-native [duplicate]

$
0
0

I have this code to upload mp3 audio to a server but it gives me [TypeError: Network request failed]Help please

export async function uploadFile(fileUri) {  const url = //my url;  var token;  await AsyncStorage.getItem('access_token').then((res) => {    token = res;  });  let data = new FormData();  data.append('file', {    uri: fileUri,    name: 'test.mp3',    type: 'audio/mpeg',  });  return fetch(url, {    method: 'POST',    headers: {      Authorization: 'Bearer '+ token,'Content-Type': 'multipart/form-data',    },    body: data,  })    .then((response) => response.json())    .catch((error) => console.error(error));}

The same exact code works fine for an image uri if I change

data.append('file', {    uri: fileUri,    name: 'test.mp3',    type: 'audio/mpeg',  });

to

 data.append('file', {    uri: fileUri,    name: 'test.jpg',    type: 'image/jpeg',  });

I'm sure the audio's uri is correct because I use the exact same way to get the uri of the image which works fine.

I tried audio/mpeg and audio/mp3 for the type but neither of them works.

TypeScript autocomplete for user defined variants tokens in React Native library

$
0
0

I am developing a React Native library that includes a Button component and a TokenManager class for managing theme-related tokens. The flow I am aiming for is as follows:

  1. In the app (App.tsx), the user defines their own token values (e.g., button variants).
  2. These tokens are then passed into the TokenManager class in the library to manage and store the values.
  3. Finally, in the Button component (Button.tsx in the library), I need to access these tokens, particularly the variants, and have TypeScript provide type suggestions for them when the Button is used in the app.

The main challenge is getting TypeScript to recognize the correct types for the tokens, especially for the variants (such as 'primary', 'secondary', 'tertiary'), and applying these types to the colorScheme prop in the Button component.

The issue:

I can't directly import the tokens from the app into the Button component, but I still need to ensure that TypeScript can correctly infer the types of the tokens in the component. Specifically, I want the colorScheme prop of the Button component to receive type suggestions for the available variants.

How can I correctly type the tokens in such a way that they are accessible in the Button.tsx component, and that TypeScript offers autocomplete and proper type checking when using them in the app?

Here’s the current code structure:

In App.tsx (user app):

// define tokensconst buttonTokens = {  variants: ['primary', 'secondary', 'tertiary'] as const, // Use 'as const' to preserve literal types  text: 'Press me',  onPress: () => console.log('Button pressed'),  colorScheme: 'primary', // 'primary' is valid because it's part of variants} as const;// set the tokensTokenStore.init(buttonTokens);

In TokenManager.ts (library):

export class TokenStore<T extends string> {    private static instance: TokenStore<any> | null = null;    private tokens!: Tokens<T>;    private constructor(tokens: Tokens<T>) {    this.tokens = tokens;    }    static init<const T extends readonly string[]>(tokens: Tokens<T[number]>) {        if (!TokenStore.instance) {            TokenStore.instance = new TokenStore<T[number]>(tokens);        }     }    static getInstance<T extends string>(): TokenStore<T> {        if (!TokenStore.instance) {            throw new Error('TokenStore has not been initialized.');        }        return TokenStore.instance as TokenStore<T>;    }    getTokens(): Tokens<T> {        return this.tokens;    }}

In Button.tsx (library):

const tokens = TokenStore.getTokens();// Button component code...

Tokens type is: Tokens<string>But I expected to be: Tokens<"primary" | "secondary" | "tertiary">

The goal is to be able to do this in any file of the app:

<Button        variants={tokens.variants}        text="Press me"        onPress={() => console.log('Button pressed')}        colorScheme="tertiary" // get suggestions from ts: "primary, secondary, tertiary"      />

So those variants ("primary", "secondary", "tertiary") depends of what user define in the tokens.

My current understanding and doubts:

I'm relatively new to TypeScript and am not sure if this is the correct approach. Are there any other strategies or workarounds I should try to achieve this? I would appreciate advice on whether this is the right direction or if there's a more effective way to handle it.

Thanks in advance to any advice.

Another navigator is already registered for this container. You likely have multiple navigators under a single NavigationContainer

$
0
0

Issue:Another navigator is already registered for this container. You likely have multiple navigators under a single "NavigationContainer" or "Screen". Make sure each navigator is under a separate "Screen" container. See https://reactnavigation.org/docs/nesting-navigators for a guide on nesting.

Code:

import React, { useState } from 'react';import { View, Text, Button } from 'react-native';import { BottomNavigation } from 'react-native-paper';import { NavigationContainer } from '@react-navigation/native';import { createStackNavigator } from '@react-navigation/stack';// Home Screensfunction HomeScreen({ navigation }) {  return (<View><Text>Home Screen</Text><Button title="Go to Details" onPress={() => navigation.navigate('Details')} /></View>  );}function DetailScreen() {  return (<View><Text>Detail Screen</Text></View>  );}// Profile Screensfunction ProfileScreen({ navigation }) {  return (<View><Text>Profile Screen</Text><Button title="Go to Profile Details" onPress={() => navigation.navigate('ProfileDetails')} /></View>  );}function ProfileDetailScreen() {  return (<View><Text>Profile Detail Screen</Text></View>  );}// Settings Screensfunction SettingsScreen() {  return <Text>Settings Screen</Text>;}// Home Stackconst HomeStack = createStackNavigator();function HomeStackScreen() {  return (<HomeStack.Navigator><HomeStack.Screen name="Home" component={HomeScreen} /><HomeStack.Screen name="Details" component={DetailScreen} /></HomeStack.Navigator>  );}// Profile Stackconst ProfileStack = createStackNavigator();function ProfileStackScreen() {  return (<ProfileStack.Navigator><ProfileStack.Screen name="Profile" component={ProfileScreen} /><ProfileStack.Screen name="ProfileDetails" component={ProfileDetailScreen} /></ProfileStack.Navigator>  );}export default function App() {  const [index, setIndex] = useState(0); // Tab index state  const [routes] = useState([    { key: 'home', title: 'Home', icon: 'home' },    { key: 'profile', title: 'Profile', icon: 'account' },    { key: 'settings', title: 'Settings', icon: 'settings' },  ]);  // Render scene based on selected tab  const renderScene = BottomNavigation.SceneMap({    home: HomeStackScreen, // Home Stack for Home tab    profile: ProfileStackScreen, // Profile Stack for Profile tab    settings: SettingsScreen, // Single screen for Settings tab  });  return (    // Wrap everything in a single NavigationContainer<NavigationContainer><BottomNavigation        navigationState={{ index, routes }}        onIndexChange={setIndex}        renderScene={renderScene}      /></NavigationContainer>  );}

React Native Expo Background Tasks continuously

$
0
0

I am currently developing an app where a user connects a bluetooth Beacon. When the distance (RSSI) gets to low an alarm (playing a loud sound) is triggered.

Now I have a question regarding background tasks:

The user should be able to lock his phone (single click on the PWR Button). Then, the app should still check if the RSSI is to low and play the sound when its triggered.

Is there a way to implement this in react native with expo?Learned React Native a few weeks ago so I am glad for any help ^^

Here is my code so far:

import React, { useState, useEffect } from "react";import { SafeAreaView, StyleSheet, Text, TouchableOpacity, View, Image, Alert } from "react-native";import useBLE from "./useBLE";import Slider from "@react-native-community/slider";import { LinearGradient } from 'expo-linear-gradient';import CheckBox from '@react-native-community/checkbox';import useAudioPlayer from './useAudioPlayer';import useLocation from "./useLocation";const audioSource = require('./img/alert.mp3');const HomeScreen = () => {  const { playSound, stopSound } = useAudioPlayer(audioSource);  let { location } = useLocation();  const {    requestPermissions,    scanForPeripherals,    stopScan,    setConnectedDevice,    setDeviceSearching,    connectedDevice,    deviceSearching,    rssi,  } = useBLE();  const [rssiAlert, setRssiAlert] = useState<boolean>(false);  const [countdown, setCountdown] = useState<number | null>(null);  const [startCountdown, setStartCountdown] = useState<boolean>(false);  const [rssiTreshold, setRssiTrheshold] = useState<number>(-70);  const [showMetaData, setShowMetaData] = useState<boolean>(false);  useEffect(() => {    if (rssi < rssiTreshold) {      setStartCountdown(true);    } else {      setStartCountdown(false);      setRssiAlert(false);      setCountdown(null);    }  }, [rssi, rssiTreshold]);  useEffect(() => {    if (startCountdown) {      setCountdown(5);      const interval = setInterval(() => {        setCountdown((prev) => {          if (prev !== null && prev > 0) {            return prev - 1;          } else {            clearInterval(interval);            setRssiAlert(true);            playSound();            console.log(location);            return null;          }        });      }, 1000);      return () => clearInterval(interval);    }  }, [startCountdown]);  const handleScan = async () => {    const isPermissionsEnabled = await requestPermissions();    if (isPermissionsEnabled) {      scanForPeripherals();    }  };  const getBarColor = () => {    if (rssi >= -50) return "green";    if (rssi >= -70) return "yellow";    return "red";  };  const resetApp = () => {    stopScan();    setConnectedDevice(null);    setStartCountdown(false);    setRssiAlert(false);    setDeviceSearching(false);    stopSound();  }  return (<LinearGradient      colors={['#d9a7c7', '#fffcdc']}      style={styles.container}><SafeAreaView style={{ flex: 1 }}><View style={styles.contentWrapper}>          {connectedDevice ? (<><Text style={styles.titleText}>Beacon verbunden!</Text><Text style={styles.titleSubText}>Du reitest jetzt sicher!</Text>              {rssiAlert ? <Image style={styles.unicornImage} source={require('./img/unicorn_smiling.png')} />                : (<Image style={styles.unicornImage} source={require('./img/unicorn_smiling.png')} />)}              {showMetaData ? (<><Text style={styles.rssiText}>RSSI: {rssi}</Text><View style={[styles.rssiBar, { width: `${100 + rssi}%`, backgroundColor: getBarColor() }]} /><Text style={styles.sliderLabel}>Schwellenwert: {rssiTreshold}</Text><Slider                  style={styles.slider}                  minimumValue={-100}                  maximumValue={-30}                  step={1}                  value={rssiTreshold}                  onValueChange={setRssiTrheshold}                  minimumTrackTintColor="red"                  maximumTrackTintColor="gray"                />                {rssi < rssiTreshold && countdown !== null && (<Text style={styles.countdownText}>Alarm in {countdown} Sekunden...</Text>                )}</>) : (<></>)}              {rssiAlert && <Text style={styles.alertText}>Ein Alarm wurde ausgelöst!</Text>}              {location && <Text style={styles.alertText}>Deine Koordinaten: {location.coords.latitude}-{location.coords.longitude}</Text>}</>          ) : (<><Text style={styles.titleText}>Bitte verbinde einen Beacon!</Text><Image style={styles.unicornImage} source={require('./img/unicorn_scanning.png')} />              {deviceSearching ? <Text>Suche Beacon...</Text> : null}</>          )}</View><TouchableOpacity          onPress={connectedDevice ? resetApp : handleScan}          style={[styles.ctaButton]}><Text style={styles.ctaButtonText}>            {connectedDevice ? "Abbrechen" : "Beacon suchen"}</Text></TouchableOpacity><View style={styles.metaData}><Text>Zeige Metadaten?</Text><CheckBox            value={showMetaData}            onValueChange={(newValue: boolean) => setShowMetaData(newValue)}          /></View></SafeAreaView></LinearGradient>  );};const styles = StyleSheet.create({  container: {    flex: 1,  },  connectedBackground: {    backgroundColor: "#90EE90",  },  contentWrapper: {    flex: 1,    justifyContent: "center",    alignItems: "center",  },  titleText: {    fontSize: 30,    fontWeight: "bold",    textAlign: "center",    marginHorizontal: 20,    color: "black"  },  titleSubText: {    fontSize: 25,    textAlign: "center",    marginHorizontal: 20,    color: "black"  },  pulse: {    marginTop: 200,  },  unicornImage: {    marginTop: 20,    height: 220,    width: 250  },  rssiText: {    fontSize: 25,    marginTop: 15,  },  alertText: {    fontSize: 20,    color: "red",    marginTop: 10,  },  countdownText: {    fontSize: 18,    color: "orange",    marginTop: 10,  },  rssiBar: {    height: 20,    borderRadius: 10,    marginTop: 10,    width: "50%",  },  sliderLabel: {    fontSize: 18,    marginTop: 20,  },  slider: {    width: 200,    height: 40,  },  ctaButton: {    backgroundColor: "#FF6060",    justifyContent: "center",    alignItems: "center",    height: 50,    marginHorizontal: 20,    marginBottom: 20,    borderRadius: 8,  },  ctaButtonText: {    fontSize: 18,    fontWeight: "bold",    color: "white",  },  metaData: {    justifyContent: "center",    alignItems: "center",    flexDirection: "row"  }});export default HomeScreen;enter code here

React Native Nested tuple autocomplete suggests all keys instead of filtering by first key

$
0
0

I am working on a TypeScript utility with react native that extracts nested keys as tuples to be used in a function. The type is supposed to provide autocomplete suggestions that are dynamically filtered based on the first selected key. However, TypeScript's autocomplete is suggesting all possible second-level keys instead of only the relevant ones under the selected first key.

React Native Component Playground

Here is a minimal example of my issue:

interface MyTheme {  colors: {    secondary: string;    tertiary: { light: string; main: string; dark: string };    gray: {      900: string;      800: { mor: string; dark: string; pink: string };      700: string;    };    constant: { white: string; black: string };  };}export type NestedKeysArray<T> = T extends object  ? {      [K in keyof T]: K extends string | number        ? T[K] extends string          ? [`${K}`]          : T[K] extends object          ? [`${K}`, ...NestedKeysArray<T[K]>]          : never        : never;    }[keyof T]  : never;const loadingColorHandler = (color: NestedKeysArray<MyTheme['colors']>) => {  console.log(color);};// ❌ Unexpected behavior:// When typing `loadingColorHandler(['tertiary', ''])`, TypeScript suggests `light, main, dark` (✅ expected),// but also `white, black, 900, 800, 700` (❌ unexpected).loadingColorHandler(['tertiary', 'black']); // This should be a type error

When entering the first key, the second key should only suggest the properties that belong to that first key.

InputExpected SuggestionsActual Suggestions (Incorrect)
['gray', '']'900', '800', '700''900', '800', '700', 'light', 'main', 'dark', 'white', 'black'
['tertiary', '']'light', 'main', 'dark'Includes unrelated keys

However, TypeScript does not properly narrow down the suggested keys and instead includes all possible second-level keys, even if they belong to unrelated objects.

How can I structure this type definition so that the autocomplete only suggests relevant keys based on the first selection? Is this a limitation of TypeScript's type system, or is there a way to refine my recursive type to achieve this behavior?

SyntaxError: C:\zero\node_modules\react-native\Libraries\Components\Touchable\TouchableOpacity.js: Missing initializer in const declaration

$
0
0

I'm trying to write tests for my React Native app (using TypeScript). All my unit tests pass without issues, but when writing component tests, I encounter the following error:

● ButtonComponent › calls onPress when pressed                                                                                                               Jest encountered an unexpected token    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.    By default "node_modules" folder is ignored by transformers.    Here's what you can do:• If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.• If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.• If you need a custom transformation specify a "transform" option in your config.• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.    You'll find more details and examples of these config options in the docs:    https://jestjs.io/docs/configuration    For information about custom transformations, see:    https://jestjs.io/docs/code-transformation    Details:    SyntaxError: C:\zero\node_modules\react-native\Libraries\Components\Touchable\TouchableOpacity.js: Missing initializer in const declaration. (330:26)        328 | }      329 |> 330 | const Touchable: component(          |                           ^      331 |   ref: React.RefSetter<React.ElementRef<typeof Animated.View>>,      332 |   ...props: Props      333 | ) = React.forwardRef((props, ref) => (       9 |      10 |     const {getByText} = render(> 11 |       <TouchableOpacity onPress={mockOnPress}>         |        ^      12 |         <Text>Click Me</Text>      13 |       </TouchableOpacity>,      14 |     );

Code:Test File:

// ButtonComponent.test.jsimport React from 'react';import {render, fireEvent} from '@testing-library/react-native';import {TouchableOpacity, Text} from 'react-native'; // Import required componentsdescribe('ButtonComponent', () => {  it('calls onPress when pressed', () => {    const mockOnPress = jest.fn();    const {getByText} = render(<TouchableOpacity onPress={mockOnPress}><Text>Click Me</Text></TouchableOpacity>,    );    fireEvent.press(getByText('Click Me')); // Simulate pressing the button    expect(mockOnPress).toHaveBeenCalled(); // Check if onPress was called  });});

Babel config:

module.exports = {  presets: ['module:metro-react-native-babel-preset','@babel/preset-react','@babel/preset-typescript','@babel/preset-env',  ],  plugins: [    ['module-resolver',      {        alias: {'@': './src',        },      },    ],    ['module:react-native-dotenv',      {        moduleName: '@env',        path: '.env',      },    ],  ],};

Jest config:

module.exports = {  preset: 'react-native',  transform: {'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',  },  moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json', 'node'], // Supports different file types  moduleNameMapper: {'^@/(.*)$': '<rootDir>/src/$1', // Optional alias to map imports'\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':'<rootDir>/__mocks__/fileMock.js','^@env$': '<rootDir>/src/types/env.d.ts',  },  transformIgnorePatterns: ['node_modules/(?!(react-native|@react-native|@react-native(-community)|react-native-gesture-handler|react-native-reanimated|@react-navigation)/)',  ],  testPathIgnorePatterns: ['/node_modules/', '/dist/'],  testEnvironment: 'node',  collectCoverage: true,  coverageReporters: ['json', 'lcov', 'text', 'clover'],  verbose: true,};

Ts config:

{"extends": "@react-native/typescript-config/tsconfig.json","compilerOptions": {"jsx": "react-native","allowJs": true,"baseUrl": ".","paths": {"@/*": ["./src/*"]    },"allowSyntheticDefaultImports": true,"strict": true,  "esModuleInterop": true,  "resolveJsonModule": true    },"typeRoots": ["./src/types", "./node_modules/@types"],"include": ["src/**/*", "./App.tsx", "__tests__"]}

Package json:

{"name": "zero","version": "0.0.1","private": true,"scripts": {"android": "react-native run-android","ios": "react-native run-ios","lint": "eslint .","start": "react-native start","test": "jest .","test:watch": "jest --watch","test:coverage": "jest --collectCoverage --coverageDirectory=\"./coverage\"","commit": "cz","prepare": "husky","pretty": "prettier --write ."  },"dependencies": {"@babel/core": "^7.26.7","@babel/runtime": "^7.26.7","@react-navigation/bottom-tabs": "^7.2.0","@react-navigation/native": "^7.0.14","@react-navigation/native-stack": "^7.2.0","@reduxjs/toolkit": "^2.5.1","axios": "^1.7.9","axios-mock-adapter": "^2.1.0","react": "18.3.1","react-native": "^0.77.0","react-native-error-boundary": "^1.2.7","react-native-fast-image": "^8.6.3","react-native-gesture-handler": "^2.22.1","react-native-keychain": "^9.2.2","react-native-reanimated": "^3.16.7","react-native-safe-area-context": "^5.1.0","react-native-screens": "^4.6.0","react-native-splash-screen": "^3.3.0","react-native-toast-message": "^2.2.1","react-native-vector-icons": "^10.2.0","react-redux": "^9.2.0"  },"devDependencies": {"@babel/plugin-transform-react-jsx": "^7.25.9","@babel/preset-env": "^7.26.7","@babel/preset-react": "^7.26.3","@babel/preset-typescript": "^7.26.0","@react-native-community/cli": "15.0.1","@react-native-community/cli-platform-android": "15.0.1","@react-native-community/cli-platform-ios": "15.0.1","@react-native/babel-preset": "^0.77.0","@react-native/eslint-config": "^0.77.0","@react-native/metro-config": "^0.77.0","@react-native/typescript-config": "^0.77.0","@testing-library/react-native": "^12.9.0","@types/jest": "^29.5.14","@types/react": "^18.3.18","@types/react-native": "^0.72.8","@types/react-native-dotenv": "^0.2.2","@types/react-native-vector-icons": "^6.4.18","@types/react-test-renderer": "^18.0.0","babel-jest": "^29.7.0","babel-plugin-module-resolver": "^5.0.2","commitizen": "^4.3.1","cz-conventional-changelog": "^3.3.0","eslint": "^8.19.0","eslint-plugin-testing-library": "^7.1.1","husky": "^9.1.7","jest": "^29.7.0","jest-react-native": "^18.0.0","metro-react-native-babel-preset": "^0.77.0","prettier": "2.8.8","react-native-dotenv": "^3.4.11","react-test-renderer": "^18.2.0","ts-jest": "^29.2.5","typescript": "5.0.4"  },"engines": {"node": ">=18"  },"config": {"commitizen": {"path": "./node_modules/cz-conventional-changelog"    }  }}

I have been stuck on this issue for 2 days and haven't found a solution. Could someone please help me with fixing the Jest configuration or guide me on how to enable Jest to handle this component correctly?

What I Tried:I configured Jest to work with React Native and TypeScript, ensuring that the necessary Babel presets were in place to handle the code transformation. I also set up custom transformIgnorePatterns to ensure that certain node_modules were included in the transformation process. I wrote a simple component test where a TouchableOpacity is pressed, and I used jest.fn() to check if the onPress callback was triggered.

What I Expected:I expected the test to run successfully, simulating a press on the button and confirming that the onPress function was called. The component test should have passed without issues.

What Actually Happened:Instead of the test passing, I encountered a SyntaxError indicating that Jest was unable to parse the TouchableOpacity component due to an issue with its syntax (missing initializer in a const declaration). The error message suggests that Jest could not transform the file correctly, which prevented the test from running

Using async/await or then in typescript but not getting any result

$
0
0

Here is code block where i am calling an axios call and promise is not resolving.I am using typescript here , version of typescript is 4

getBalance = async (address: string) => {        let endpoints = this.getBalanceEndpoint();        for (let i = 0; i < endpoints.length; i++) {          let endpoint = endpoints[i];          const url = endpoint + address +'?details=basic';          const param: object = {            method: 'get',            url: url,            headers: {'User-Agent': UA,            },            timeout: 1000,          };          try {            console.log(param,"Balance Params")            **const response = await axios(param)**;            console.log(response,"BITCOIN BALANCE")            }          } catch (e) {            console.log(e)          }          await new Promise(resolve =>            setTimeout(resolve, GENERIC_REQUEST_THROTTLE_DELAY)          );        }        throw new Error('Unable to retrieve balance!');      };

I am not getting any result or promise is not resolving in await axios call.

Please let me know answer


tsconfig.json shows error: Entry point for implicit type library 'glob'

$
0
0

I have a Monorepo which uses Typescript. I have a common folder which shows this error on the top of the file -> Entry point for implicit type library 'glob'. I am not sure what is wrong with the configuration.

Screenshot:

enter image description here

tsconfig.json

{"extends": "../../tsconfig.json","compilerOptions": {"allowJs": true,"allowSyntheticDefaultImports": true,"esModuleInterop": true,"isolatedModules": true,"jsx": "react-native","lib": ["es2021"    ],"moduleResolution": "node","noEmit": false,"strict": true,"target": "esnext","composite": true,"rootDir": ".","outDir": "dist","declaration": true,"emitDeclarationOnly": true,"declarationMap": true},"exclude": ["node_modules",]}

Any Suggestions?

ReferenceError: Can't find variable: TextEncoder

$
0
0

I'm using VSCode/Typescript React 3.4.3 for a React Native project and I'm having troubles at runtime with TextEncoder

The ts code:

...var encoder = new TextEncoder();var b: Uint8Array = encoder.encode(newName);...

My tsconfig libs:

"module": "es2015","target": "es2015","jsx": "react","lib": ["es5", "es2017", "dom"]

This compile fines but it fails at runtime when it tries to create the instance of TextEncoder:

"ReferenceError: Can't find variable: TextEncoder"

I do not understand what is wrong here.

Any help appreciated

EDIT 1: Well the fact is that when you debug your JS code, it runs in Chrome which leads to success. But when you're not, you finish to discover that the JavaScriptCore neither support TextEncorder nor btoa.

So I have chosen to favor the use of npm modules (text-encoding and base-64):

import * as encoding from 'text-encoding';import {encode as btoa} from 'base-64'...var encoder = new encoding.TextEncoder();...

How can I resolve the error "the expected type comes from property 'component' which is declared here on type"?

$
0
0

In my code here, I am trying to create a Stack Navigator.

This is the stack navigator I have made.

import React from 'react';import { View, Text, StyleSheet } from 'react-native';import { createStackNavigator } from '@react-navigation/stack';import EnterPassword from '../screens/EnterPassword';import EnterAccount from '../screens/EnterAccount';const GoogleLoginStack = createStackNavigator();const GoogleLogin = () => {    return (<GoogleLoginStack.Navigator><GoogleLoginStack.Screen name='EnterAccount' component={EnterAccount} /><GoogleLoginStack.Screen name='EnterPassword' component={EnterPassword} /></GoogleLoginStack.Navigator>    )};export default GoogleLogin;

It is then used in App.tsx file where:

...<Stack.Screen name="Login" component={Login} /><GoogleLogin /><Stack.Screen name="SignUp" component={SignUp} />...

The screen I have created is as follow:

import React from 'react';import { View, Text, StyleSheet } from 'react-native';const EnterAccount = (props: any) =>  {<View style={styles.screen}><Text>            Enter Account Screen</Text></View>}const styles = StyleSheet.create({    screen: {        flex: 1,        justifyContent: 'center',        alignItems: 'center',    }})export default EnterAccount;

However, I am getting this error:Error text: https://i.sstatic.net/zKbAa.png

I understand that it is because of how I defined the type of props to be but I am unsure of what's the right way to define the type of props.

Thank you so much for your help!

"Command PhaseScriptExecution failed with a nonzero exit code" while creating an ios build

$
0
0

I ran into a "Command PhaseScriptExecution failed with a nonzero exit code" while creating an ios build.

XCode 15.3React Native 0.74.

Please help!

I'm just stuck at it

Please help!!!

I ran into a "Command PhaseScriptExecution failed with a nonzero exit code" while creating an ios build.

XCode 15.3React Native 0.74.

Please help!

I'm just stuck at it

Please help!!!

How to navigate handleSubmit property in Amplify Authenticator.SignUp to ConfirmSignUp?

$
0
0

Devs.I'm currently developing an iOS app using React Native and the Amplify UI Library, and I have been struggling to setup navigation in Authenticator.

[What I want to do]I would like to swich the screen from SignUp to ConfirmSignUp when I push the Submit button on the SignUp screen.To accomplish it, how should I code in the handleSubmit property of Authenticator.SignUp in SignUp.tsx?

I'm using Authenticator.SignUp and Authenticator.ConfirmSignUp like below.

const components = {  SignUp: (props: any) => <SignUp {...props} />,  ConfirmSignUp: (props: any) => <ConfirmSignUp {...props} />,};<Authenticator.Provider><Authenticator          components={{            SignUp: components.SignUp,            ConfirmSignUp: components.ConfirmSignUp,          }}        /></Authenticator.Provider>

Custom SignUp and ConfirmSignUp components are like below.

[SignUp.tsx]

export const SignUp = (props: any) => {  const { route } = useAuthenticator((context) => [context.route]);  const navigation = useNavigation<NavigationProp<RootStackParamList>>();  return (<Authenticator.SignUp          {...props}          handleSubmit={async (formData: {            username: string;            password: string;            email: string;          }) => {            try {              const { isSignUpComplete, nextStep } = await signUp({                username: formData.username,                password: formData.password,                options: {                  userAttributes: {                    email: formData.email,                  },                },              });              if (                !isSignUpComplete &&                nextStep.signUpStep === "CONFIRM_SIGN_UP"              ) {                 *** How should I code here? ***                });              }            } catch (error) {              alert("You couldn't sign up for some reasons.");              console.log(error);            }          }}        />

[ConfirmSignUp.tsx]

export const ConfirmSignUp = (props: any) => {  return (<Authenticator.ConfirmSignUp      {...props}      handleSubmit={async (formData: { confirmation_code: string }) => {        try {          const { isSignUpComplete, nextStep } = await confirmSignUp({            username: props.route.params.username,            confirmationCode: formData.confirmation_code,          });        } catch (error) {          console.log(error);        }      }}    />  );};

Thank you in advance!

I read the Full API section in the Amplify UI Docs, but I couldn't find anything about navigating to the ConfirmSignUp screen.I tried to use useNavigation to navigate from SignUp to ConfirmSignUp, but I couldn't make it work.

React UI Not Displaying Backend API Response

$
0
0

I have a React application that makes a POST request to a backend API to process an image. The backend correctly processes the request and returns the expected response. However, the UI is not displaying the output correctly.

import React, { useState } from "react";import axios from "axios";import { useDropzone } from "react-dropzone";interface ExtractedData {  company: string;  invoice_date: string;  items: { description: string; quantity: number; amount: string }[];  // Changed amount to string for "$745.00" format  total_amount: string;  practitioner: string;  patient: string;  location: string;  currency: string | null;  other_details?: string;}const ImageUploadOCR: React.FC = () => {  const [image, setImage] = useState<File | null>(null);  const [data, setData] = useState<ExtractedData | null>(null);  const [loading, setLoading] = useState<boolean>(false);  const { getRootProps, getInputProps } = useDropzone({    accept: { "image/*": [] },    onDrop: (acceptedFiles) => setImage(acceptedFiles[0]),  });  const handleUpload = async () => {    if (!image) return;    setLoading(true);    const formData = new FormData();    formData.append("image", image);    try {      console.log("Data disk reached");      const response = await axios.post("http://localhost:5000/api/extract", formData, {        headers: { "Content-Type": "multipart/form-data" },      });      // Log the full response to verify the structure      console.log("Response data:", response.data);      // Set data to the state      setData(response.data);      // Optionally log company and invoice_date for debugging      console.log("Company:", response.data?.company);      console.log("Invoice Date:", response.data?.invoice_date);    } catch (error) {      console.error("Error uploading image:", error);    } finally {      setLoading(false);    }  };  return (<div className="p-6 max-w-2xl mx-auto"><div {...getRootProps()} className="border-2 border-dashed p-4 cursor-pointer text-center"><input {...getInputProps()} />        {image ? <p><img src={URL.createObjectURL(image)} /></p> : <p>Drag & drop an image, or click to select</p>}</div><button className="mt-4 bg-blue-500 text-white px-4 py-2 rounded" onClick={handleUpload} disabled={!image || loading}>        {loading ? "Processing..." : "Upload & Extract"}</button>      {data && (<div className="mt-6"><h2 className="text-xl font-bold mb-2">Extracted Data</h2><table className="w-full border-collapse border border-gray-300"><thead><tr><th className="border p-2">Field</th><th className="border p-2">Value</th></tr></thead><tbody><tr><td className="border p-2">Company</td><td className="border p-2">{data?.company || "Not available"}</td> {/* Optional chaining added */}</tr><tr><td className="border p-2">Invoice Date</td><td className="border p-2">{data?.invoice_date || "Not available"}</td> {/* Optional chaining added */}</tr></tbody></table><h3 className="text-lg font-bold mt-4">Items</h3><table className="w-full border-collapse border border-gray-300"><thead><tr><th className="border p-2">Description</th><th className="border p-2">Quantity</th><th className="border p-2">Amount</th></tr></thead><tbody>              {data.items.map((item, index) => (<tr key={index}><td className="border p-2">{item.Description}</td><td className="border p-2">{item.Quantity}</td><td className="border p-2">{item.Amount}</td></tr>              ))}</tbody></table></div>      )}</div>  );};export default ImageUploadOCR;

Issue:The API returns the expected result, but the UI does not display the image.No errors are shown in the console.

Backend response:

{'Currency': None, 'Location': {'Patient Address': '11 Rosewood Drive, Collingwood, NY 33580', "Physician's Address": '102 Trope Street, New York, NY 45568'}, 'Other relevant details': {'Due date': '07/30/23', 'Invoice number': '12245', 'Prescription note': 'A prescription has been written out for patient, for an acute throat infection.', 'Sub total': '$745.00', 'Tax amount': '$157.05', 'Tax rate': '9%'}, 'Patient': 'Kemba Harris', 'Practitioner': 'Dr. Alanah Gomez', 'Total Amount': '$1,902.05', 'company': 'Unknown', 'invoice_date': '07/01/23', 'items': [{'amount': '$745.00', 'description': 'Full Check Up', 'quantity': 1}, {'amount': '$1,000.00', 'description': 'Ear & Throat Examination', 'quantity': 1}]}

image after called successful:

enter image description here

How can I properly display the image output in the UI? What could be causing the issue?

expo-background-fetch - task is never executed

$
0
0

Using example and following tutorial for expo-background-fetch I didn't see the function triggered. (https://docs.expo.dev/versions/latest/sdk/background-fetch/)

Same with the following code:

import React, { useEffect, useState } from 'react';import { StyleSheet, Text, View } from 'react-native';import * as BackgroundFetch from 'expo-background-fetch';import * as TaskManager from 'expo-task-manager';const BACKGROUND_FETCH_TASK = 'background-fetch';function myTask() {  try {    // Fetch data here...    const backendData = "Simulated fetch " + new Date().toLocaleString();    console.log("myTask() ", backendData);    return backendData; // Return the fetched data directly  } catch (err) {    console.error('Error fetching data:', err);    return null;  }}export async function initBackgroundFetch() {  console.log("Init Background Fetch");  try {    if (!TaskManager.isTaskDefined(BACKGROUND_FETCH_TASK)) {      TaskManager.defineTask(BACKGROUND_FETCH_TASK, myTask);    }    const options = {      minimumInterval: 1 * 60    };    await BackgroundFetch.registerTaskAsync(BACKGROUND_FETCH_TASK, options);  } catch (err) {    console.log("registerTaskAsync() failed:", err);  }}async function unregisterBackgroundFetchAsync() {  return BackgroundFetch.unregisterTaskAsync(BACKGROUND_FETCH_TASK);}export default function BackgroundFetchScreen() {  const [isRegistered, setIsRegistered] = useState(false);  const [status, setStatus] = useState(null);  const [backendData, setBackendData] = useState(null);  useEffect(() => {    initBackgroundFetch();    checkStatusAsync();  }, []);  const fetchData = async () => {    try {      const data = await myTask();      setBackendData(data);    } catch (error) {      console.error('Error fetching data:', error);    }  };  useEffect(() => {    fetchData(); // Fetch data when component mounts  }, []);  const checkStatusAsync = async () => {    const status = await BackgroundFetch.getStatusAsync();    const isRegistered = await TaskManager.isTaskRegisteredAsync(BACKGROUND_FETCH_TASK);    setStatus(status);    setIsRegistered(isRegistered);  };  return (<Text>      Background:{''}<Text style={styles.boldText}>        {status && BackgroundFetch.BackgroundFetchStatus[status]}</Text>      Status:{''}<Text style={styles.boldText}>        {isRegistered ? "Registered" : 'Not registered yet!'}</Text>      Last update:{''}<Text style={styles.boldText}>        {backendData ? backendData : 'No data fetched yet!'}</Text></Text>  );}const styles = StyleSheet.create({  screen: {    flex: 1,    justifyContent: 'center',    alignItems: 'center',  },  textContainer: {    margin: 10,  },  boldText: {    fontWeight: 'bold',  },});

From the previous snippet i get only the following output, also waiting a long time:

 LOG  Init Background Fetch LOG  myTask()  Simulated fetch 10/04/2024, 14:48:27

I'm running expo with npx expo start on a windows machine targeting an ipad (ios) that runs expo go.

There are known bugs o specific example for that use?

Thanks


How to share screens between navigators with Typescript?

$
0
0

Given the situation where I want different tabs of a BottomTabNavigator to share some screens while still showing the tab bar, the problem is type cheking for the navigation prop.

So far I've managed to get this, but I get 'type string is not assignable to type ParamListBase' ts(2344)

types.ts

export type SharedNavigatorParams = {  Screen1: undefined  Screen2: undefined}export type TabParams = SharedNavigatorParams & {    HomeTab: NavigatorScreenParams<HomeTabParams>    ProfileTab: NavigatorScreenParams<ProfileTabParams>}export type HomeTabParams = SharedNavigatorParams & {  Home: undefined}export type ProfileTabParams = SharedNavigatorParams & {  Profile: undefined}export type TabScreenProps<T extends keyof TabParams> = BottomTabScreenProps<TabParams, T>export type HomeTabScreenProps<T extends keyof HomeTabParams> =  CompositeScreenProps<    NativeStackScreenProps<HomeTabParams, T>,    BottomTabScreenProps<keyof TabParams>    // <-- ts error >                                          export type ProfileTabScreenProps<T extends keyof ProfileTabParams> =  CompositeScreenProps<    NativeStackScreenProps<ProfileTabParams, T>,    BottomTabScreenProps<keyof TabParams>    // <-- same error>declare global {  namespace ReactNavigation {    interface RootParamList extends TabParams {}  }}

Doing the following works, but it is not the way its done in the react navigation docs

export type HomeTabScreenProps<T extends keyof HomeTabParams> = CompositeScreenProps<    NativeStackScreenProps<HomeTabParams, T>,    BottomTabScreenProps<AppTabParams, keyof AppTabParams>>

Navigation.tsx

export default function TabNavigator() {  return<Tab.Navigator><Tab.Screen name="HomeTab" component={HomeTabNavigator}/><Tab.Screen name="HomeTab" component={ProfileTabNavigator}/></Tab.Navigator>}function HomeTabNavigator() {  return<HomeTab.Navigator><HomeTab.Screen name="Home" component={Home} /><HomeTab.Screen name="Screen1" component={Screen1} /><HomeTab.Screen name="Screen2" component={Screen2} /></HomeTab.Navigator>}function ProfileTabNavigator() {  return<ProfileTab.Navigator><ProfileTab.Screen name="Profile" component={Profile} /><ProfileTab.Screen name="Screen1" component={Screen1} /><ProfileTab.Screen name="Screen2" component={Screen2} /></ProfileTab.Navigator>}

Note that I have to add a <Stack.Screen ... /> for each shared screen on every tab, which doesn't look so good to me.

So when I want to use the navigation prop, I'd do as it's shown in the pictures. Although it works, it is not the expected behavior.

importing navigation prop

image description

I'm really struggling to make this work properly, these are the resources I've been basing this code on, plus many stack overflow questions:

This github issue: https://github.com/react-navigation/react-navigation/issues/3790

BlueSky: https://github.com/bluesky-social/social-app/blob/main/src/Navigation.tsx

React Navigation docs: https://reactnavigation.org/docs/typescript

"@react-navigation/native": "^7.0.14"

"@react-navigation/native-stack": "^7.2.0"

"@react-navigation/bottom-tabs": "^7.2.0"



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>