React Native WhatsApp clone: LongPress selection not updating state immediately

i am making a whatsapp clone in react native and having a problem regarding archiving the chats

i had maked the add chats functionallity in it and when i longpress the chat a navbar like whatsapp is appearing on the top that consists of many of functionallities in which one of them is archive chat when i archive the chat i am deleting the chat from the original chats array and moving it into an array of named arhievedChats and like of whatsapp i had maked a Button wrapping the View inside it is the text Archived and when i click that button i am navigating to other screen named Archived and there i am rendering the arhievedChats array using the Flatlist and just like the chat screen i want to make a functionallity on this screen also that when the user longPress the chat a navbar should appear on the top that consists of un-archiveChat functionallity but first i want to select the chat for that i have a selected property inside that arhievedChats array and when i longPress the chat i want to toggle that property to true and if the selected property is true a tick mark should appear on the chat but when i am longpressing the chat at that time the tick mark is not appearing but when i go back and add another chat and then archive it and come to the Arhchive screen again then the chat that i longpressed earlier is becoming selected

//Archived.js

import {
  StyleSheet,
  Text,
  FlatList,
  View,
  Animated,
  Image,
  TouchableOpacity,
} from "react-native";
import React, { useCallback, useEffect, useRef } from "react";
import Chat from "./Chat";
import { AntDesign, Ionicons } from "react-native-vector-icons";
import {
  ACTIVE_TAB_GREEN_COLOR,
  CHAT_BACKROUND_COLOR,
  CHAT_DATA_STATUS_COLOR,
  TAB_BACKGROUND_COLOR,
} from "./WhatsappMainScreen";
import { navbarAnimation } from "./RippleButton";

const Archived = ({ route }) => {
  const checkedAnimaton = new Animated.Value(0);
  const {archived,setarchived} = route.params;
  

 const makeTickAnmation = () => {
    Animated.timing(checkedAnimaton,{
      toValue:1,
      duration:500,
      useNativeDriver:true
    }).start()
 }

  const findArchiveItemsToSelect = (key) => {
    let newChats = [...archived];
    const SelectedArchiveChats = newChats.map(chat => {
      if(chat.key == key){
        return {
          ...chat,
          selected:true
        }
      }
      return chat;
    });
    setarchived(SelectedArchiveChats)
  }

  return (
    <>
      <View style={{ flex: 1, backgroundColor: CHAT_BACKROUND_COLOR }}>
        <View
          style={[
            styles.arhivedText,
            { borderBottomWidth: 1, borderBottomColor: TAB_BACKGROUND_COLOR },
          ]}
        >
          <Text style={{ color: CHAT_DATA_STATUS_COLOR, textAlign: "center" }}>
            These chats stay archived when new messages are received.
          </Text>
        </View>
        <FlatList
        
        data={archived}
        keyExtractor={item => item.key}
        ItemSeparatorComponent={() => {
          return (
            <View
              style={{ height: 1, backgroundColor: TAB_BACKGROUND_COLOR }}
            ></View>
          );
        }}
        renderItem={({item}) => {
          const ItemData = {
            ...item,
            LeftPlaceRenderThing: ({ handleOpenDpModel }) => {
              return (
                <>
                  <Animated.View
                    style={{
                      zIndex: 111,
                      transform: [{ scale: checkedAnimaton }],
                    }}
                    onLayout={item.selected ? () => makeTickAnmation(): () => {}}
                  >
                    {item.selected ? (
                      <Ionicons
                        name="checkmark-done-circle-sharp"
                        color={ACTIVE_TAB_GREEN_COLOR}
                        size={20}
                        style={{
                          fontSize: 20,
                          transform: [
                            { translateX: 40 },
                            { translateY: 15 },
                          ],
                        }}
                      />
                    ) : null}
                  </Animated.View>
                  <TouchableOpacity
                    onPress={() => handleOpenDpModel(item.photo, item.name)}
                  >
                    <View
                      style={{
                        justifyContent: "center",
                        alignItems: "center",
                      }}
                    >
                      <Image
                        source={
                          item.photo
                            ? { uri: item.photo }
                            : require("./Images/profile.png")
                        }
                        style={{
                          height: 55,
                          aspectRatio: 1,
                          borderRadius: 50,
                          marginLeft: item.selected ? -20 : 0,
                        }}
                        resizeMode="contain"
                      />
                    </View>
                  </TouchableOpacity>
                </>
              );
            },
            RightPlaceRenderThing:() => null,
            NotshowChatMakingDate: false,
            onLongPress:() => {
              findArchiveItemsToSelect(item.key);
              makeTickAnmation()
            }
          }
          return <Chat {...ItemData}/>
        }}
        />
      </View>
    </>
  );
};

export default Archived;

const styles = StyleSheet.create({
  arhivedText: {
    padding: 15,
  },
});

WhatsappNavbar.js

import {
  StyleSheet,
  Text,
  View,
  StatusBar,
  Animated,
  TextInput,
  Alert,
} from "react-native";
import React, { useCallback, useEffect, useRef, useState } from "react";
import Camera from "react-native-vector-icons/Feather";
import Search from "react-native-vector-icons/Fontisto";
import {
  ClosenavbarAnimation,
  RippleButton,
  navbarAnimation,
  showToast,
} from "./RippleButton";
import { AntDesign } from "@expo/vector-icons";
import { MaterialIcons } from "@expo/vector-icons";
import { FontAwesome5 } from "@expo/vector-icons";
import { Ionicons } from "react-native-vector-icons";
import SimpleLineIcons from "react-native-vector-icons/SimpleLineIcons";

import {
  TAB_BACKGROUND_COLOR,
  INACTIVE_TAB_WHITE_COLOR,
  TITLE_COLOR,
  CHAT_DATA_STATUS_COLOR,
  BADGE_BACKGROUND_COLOR,
} from "./WhatsappMainScreen";

const WhatsAppNavbar = ({
  selected,
  chats,
  setchats,
  opensearchBar,
  setopensearchBar,
  FileredChats,
  setFileredChats,
  archived,
  setarchived
}) => {
  const badgesData = [
    { badgeText: "Unread", badgeIcons: "mark-chat-unread", size: 22, key: 1 },
    { badgeText: "Photos", badgeIcons: "photo", size: 22, key: 2 },
    { badgeText: "Videos", badgeIcons: "videocam", size: 22, key: 3 },
    { badgeText: "Links", badgeIcons: "insert-link", size: 25, key: 4 },
    { badgeText: "GIFs", badgeIcons: "gif", size: 25, key: 5 },
    { badgeText: "Audio", badgeIcons: "audiotrack", size: 25, key: 6 },
    { badgeText: "Documents", badgeIcons: "contact-page", size: 20, key: 7 },
    { badgeText: "Polls", badgeIcons: "poll", size: 20, key: 8 },
  ];

  const selectedNavbarAnimation = useRef(new Animated.Value(0)).current;
  const searchNavbarAnimation = useRef(new Animated.Value(0)).current;

  const inputRef = useRef(null);

  const [value, setValue] = useState("");

  useEffect(() => {
    if (selected) {
      navbarAnimation(selectedNavbarAnimation);
    } else {
      ClosenavbarAnimation(selectedNavbarAnimation);
    }
  }, [selected]);

  useEffect(() => {
    if (opensearchBar) {
      navbarAnimation(searchNavbarAnimation);
    } else {
      ClosenavbarAnimation(searchNavbarAnimation);
    }
  }, [opensearchBar]);

  const handleOpenSearchBar = () => {
    setopensearchBar(!opensearchBar);
  };

  const searchNavbarInterpolation = searchNavbarAnimation.interpolate({
    inputRange: [0, 1],
    outputRange: [410, 0],
  });

  const searchNavbarStyles = {
    transform: [{ translateX: searchNavbarInterpolation }],
  };

  const handlePinChat = useCallback(() => {
    let newchats = [...chats];
    const selectedChats = newchats.map((chat) => {
      if (chat.selected) {
        return {
          ...chat,
          pinned: !chat.pinned,
        };
      }
      return chat;
    });
    setchats(selectedChats);
    showToast("Pinned chat");
  }, [setchats, chats]);

  const handleMuteChat = useCallback(() => {
    let newchats = [...chats];
    const selectedChats = newchats.map((chat) => {
      if (chat.selected) {
        return {
          ...chat,
          muted: !chat.muted,
        };
      }
      return chat;
    });
    setchats(selectedChats);
    showToast("Chat muted");
  }, [chats, setchats]);

  const hanldeArchieveChat = useCallback(() => {
    let newchats = [...chats];
    const archievedChats = newchats.filter((chat) => chat.selected);
    const unSelectChatsArchived = archievedChats.map((chat) => {
      if (chat.selected) {
        return { ...chat, selected: false};
      }
      return chat;
    });


    setarchived((prevArchived) => [...prevArchived,...unSelectChatsArchived]);

    const deletedChats = newchats.filter((chat) => {
      if (chat.selected) {
        return;
      }
      return chat;
    });
    setchats(deletedChats);
    showToast(
      `${unSelectChatsArchived.length} chat${
        unSelectChatsArchived.length > 1 ? "s" : ""
      } Archieved`
    );
  }, [chats, setchats, setFileredChats,setarchived]);

  const handleFilterChats = (vlue) => {
    setValue(vlue);

    if (vlue == "") {
      setchats(FileredChats);
    } else {
      const FilteredItems = chats.filter((chat) => {
        return chat.name.toLowerCase().includes(vlue.toLowerCase());
      });

      if (FilteredItems.length > 0) {
        setchats(FilteredItems);
      } else {
        setchats(FileredChats);
      }
    }
  };

  const selectedChats = chats.filter((chat) => {
    if (chat.selected) {
      return chat;
    }
  });

  const handleDeleteChat = useCallback(() => {
    let newchats = [...chats];
    const deletedChats = newchats.filter((chat) => {
      if (chat.selected) {
        return;
      }
      return chat;
    });

    Alert.alert(
      `Delete ${selectedChats.length > 1 ? selectedChats.length : "this"} Chat${
        selectedChats.length > 1 ? "s" : ""
      } ?`,
      "Messages will only be removed from this device and your devices on the newer versions of the Whatsapp",
      [
        {
          text: "Cancel",
          onPress: () => null,
          style: "cancel",
        },
        { text: "OK", onPress: () => setchats(deletedChats) },
      ],
      { cancelable: true }
    );

    showToast("Chat deleted");
  }, [chats, setchats]);

  return (
    <>
      <StatusBar backgroundColor={TAB_BACKGROUND_COLOR} />

      <Animated.View
        style={[
          styles.searchNavbarContainer,
          { backgroundColor: TAB_BACKGROUND_COLOR },
          searchNavbarStyles,
        ]}
      >
        <View style={[styles.input_and_arrow_container]}>
          <RippleButton onPress={() => setopensearchBar(false)}>
            <AntDesign
              name="arrowleft"
              size={26}
              color={CHAT_DATA_STATUS_COLOR}
            />
          </RippleButton>
          <TextInput
            style={styles.Searchinput}
            placeholder="Search..."
            placeholderTextColor={CHAT_DATA_STATUS_COLOR}
            value={value}
            onChangeText={handleFilterChats}
            ref={inputRef}
          />
        </View>
        <View style={[styles.badgesContainer]}>
          {badgesData.map((badge) => {
            return (
              <View
                key={badge.key}
                style={[
                  styles.badge,
                  { backgroundColor: BADGE_BACKGROUND_COLOR, height: 35 },
                ]}
              >
                <View style={styles.badgeIcon}>
                  <MaterialIcons
                    name={badge.badgeIcons}
                    size={badge.size}
                    color={CHAT_DATA_STATUS_COLOR}
                  />
                </View>
                <View style={styles.badgeText}>
                  <Text style={{ color: TITLE_COLOR }}>{badge.badgeText}</Text>
                </View>
              </View>
            );
          })}
        </View>
      </Animated.View>

      <Animated.View
        style={[
          styles.selectedChatNavbar,
          {
            backgroundColor: TAB_BACKGROUND_COLOR,
            transform: [{ scaleX: selectedNavbarAnimation }],
          },
        ]}
      >
        <View style={styles.chatsCountContainer}>
          <RippleButton
            onPress={() => ClosenavbarAnimation(selectedNavbarAnimation)}
          >
            <AntDesign name="arrowleft" size={24} color={TITLE_COLOR} />
          </RippleButton>
          <Text style={{ fontSize: 20, marginLeft: 15, color: TITLE_COLOR }}>
            {selectedChats.length}
          </Text>
        </View>
        <View
          style={[
            styles.iconContainer,
            { justifyContent: "center", alignItems: "center" },
          ]}
        >
          <RippleButton onPress={handlePinChat}>
            {/* <MaterialCommunityIcons name="pin-off" size={21} color={TITLE_COLOR} /> */}
            <AntDesign name="pushpin" size={21} color={TITLE_COLOR} />
          </RippleButton>
          <RippleButton onPress={handleDeleteChat}>
            <MaterialIcons name="delete" size={21} color={TITLE_COLOR} />
          </RippleButton>
          <RippleButton onPress={handleMuteChat}>
            <FontAwesome5 name="volume-mute" size={21} color={TITLE_COLOR} />
          </RippleButton>
          <RippleButton onPress={hanldeArchieveChat}>
            <Ionicons name="archive-outline" size={21} color={TITLE_COLOR} />
          </RippleButton>
          <RippleButton>
            <SimpleLineIcons
              name="options-vertical"
              color={TITLE_COLOR}
              size={18}
            />
          </RippleButton>
        </View>
      </Animated.View>

      <View
        style={[
          styles.navbarContainer,
          { backgroundColor: TAB_BACKGROUND_COLOR },
        ]}
      >
        <View style={styles.textContainer}>
          <Text
            style={[styles.whatsappText, { color: INACTIVE_TAB_WHITE_COLOR }]}
          >
            WhatsApp
          </Text>
        </View>
        <View style={styles.iconContainer}>
          <RippleButton>
            <Camera name="camera" color={INACTIVE_TAB_WHITE_COLOR} size={18} />
          </RippleButton>
          <RippleButton onPress={handleOpenSearchBar}>
            <Search name="search" color={INACTIVE_TAB_WHITE_COLOR} size={18} />
          </RippleButton>
          <RippleButton>
            <SimpleLineIcons
              name="options-vertical"
              color={INACTIVE_TAB_WHITE_COLOR}
              size={18}
            />
          </RippleButton>
        </View>
      </View>
    </>
  );
};

export default WhatsAppNavbar;

const styles = StyleSheet.create({
  navbarContainer: {
    paddingHorizontal: 10,
    paddingVertical: 15,
    justifyContent: "space-between",
    alignItems: "center",
    flexDirection: "row",
  },
  whatsappText: {
    fontSize: 20,
    fontWeight: "600",
    marginLeft: 8,
  },
  Searchinput: {
    padding: 10,
    flex: 1,
    paddingLeft: 10,
    borderWidth: 0,
    height: 50,
    fontSize: 17,
    marginLeft: 10,
    color: "white",
  },
  badgesContainer: {
    flex: 1,
    marginHorizontal: 14,
    flexDirection: "row",
    flexWrap: "wrap",
    gap: 10,
  },
  searchNavbarContainer: {
    height: 210,
    width: "100%",
    position: "absolute",
    zIndex: 55555,
    justifyContent: "space-between",
    backgroundColor: "red",
  },
  input_and_arrow_container: {
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
    padding: 5,
  },
  badge: {
    flexDirection: "row",
    width: "30%",
    justifyContent: "space-around",
    alignItems: "center",
    padding: 8,
    borderRadius: 20,
  },
  iconContainer: {
    flexDirection: "row",
    gap: 2,
  },
  selectedChatNavbar: {
    width: "100%",
    height: "8%",
    backgroundColor: "red",
    position: "absolute",
    zIndex: 2222,
    flexDirection: "row",
    justifyContent: "space-between",
    top: 0,
  },
  iconContainer: {
    flexDirection: "row",
    gap: 2,
  },
  chatsCountContainer: {
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
  },
});

typescript chatAt funcation exist on type

I have a problem, there are 2 number values ​​on the route, for example localhost:8000/basket/00

I am trying to call number 2 on this route with the charat function, but there is a red line under the charat function and it gives me an error

const donationIndex = Number(route.params.id.charAt(0));
const detailIndex = Number(route.params.id.charAt(1));
const donation = ref(store.getters.currentSepet.donations[route.params.id.charAt(0)]);
const donationDetail = ref(
  store.getters.currentSepet.donations[route.params.id.charAt(0)].details[route.params.id.charAt(1)]
);

enter image description here

Make regex match a pattern repeatedly

I want to repetedly capture a certain pattern. My pattern is #|X|#YYY, where X is any single letter, and YYY is any string, and the # and | characters are hardcoded separator characters.

For example, this is my Input String: #|m|#this is string #1#|m|#this is string #2#|m|#this is string #3

This is my desired output:

Match:
 - Group 1: m
 - Group 2: this is string #1
Match:
 - Group 1: m
 - Group 2: this is string #2
Match:
 - Group 1: m
 - Group 2: this is string #3

I tried this:

const pattern = /#|(w+)|#(.*)/g;
const input = "#|m|#this is string #1#|m|#this is string #2#|m|#this is string #3";

let match;
while ((match = pattern.exec(input)) !== null) {
  const group1 = match[1];
  const group2 = match[2];
  console.log("Match:");
  console.log("- Group 1:", group1);
  console.log("- Group 2:", group2);
}

but it seems to capture too gredily and only outputs one match:

Match:
 - Group 1: m
 - Group 2: this is string #1#|m|#this is string #2#|m|#this is string #3

When I try to make the pattern ungreedy, I get 3 matches as desired, but group 2 is empty for some reason.

Ungreedy attempt: (notice the ?)

const pattern = /#|(w+)|#(.*?)/g;

Output:

Match:
 - Group 1: m
 - Group 2: 
Match:
 - Group 1: m
 - Group 2: 
Match:
 - Group 1: m
 - Group 2: 

What am I doing wrong? How can I make it match the whole string until the next occurence to get my desired output?

Why isn’t useState updating my array in React Native with async-await functions? [duplicate]

cards useState not updating in React Native but the array is updated

const [cards, setCards] = useState([]);
let array = [];

useEffect(() => {
        const fetchData = async () => {
          try {
            const response = await getInventory();
            let x = response.data;
            setCards(x);
            console.log(x);
            console.log(cards);
            array = x;
            
         } catch (error) {
           console.error(error);
        }
      };
      
        fetchData();
      }, []);

I tried to put the cards in the square brackets and then it went into a loop so that the first time it printed an empty array and the other times it printed the array with the desired information that comes from the server, so my conclusion is that it doesn’t happen the first time but it does the following times

How to use apollo-link-rest to query array of objects?

I am trying to use apollo-link-rest to query this dictionary API – https://api.dictionaryapi.dev/api/v2/entries/en/test.

The API returns an array of objects which are the definition of the words but for some reason I can’t structure my gql query properly to return a result.

My query is like so:

const Query = gql`
  query Definitions {
    definitions @rest(type: "Definition", path: "test") {
      results @rest(type: "Word") {
        word
      }
    }
  }
`;

And I have setup my restLink like so:

const restLink = new RestLink({ 
  uri: "https://api.dictionaryapi.dev/api/v2/entries/en" 
});

However, when I log my result, I end up with this:

const {
  data,
  error,
  loading
} = useQuery(Query, {
  variables: {
    searchInput: "test"
  }
});

console.log("res:", {
  data,
  error,
  loading
}) // {"data": {"definitions": null}, "error": undefined, "loading": false}

I was expecting:

{"data": {"definitions": [{word: "test", ...}]}, "error": undefined, "loading": false}

I feel like my GQL query doesn’t match the expected response of the rest API but I am unsure what this should look like considering the response is an array of data. Perhaps I need to set the types to something else?

How can I structure my query so that I can get the expected array response my the dictionary API?

How can I find unique tracking numbers in one MongoDB collection that are not present in another, given large collections?

I have two collections in MongoDB named colors and cities. Each collection has 150k documents. Both collections has a column called tracking_numbers. I need unique tracking numbers of colors collection that are not present in the cities collection. Actually I wrote the code in NodeJS using mongoose, it is taking few seconds for finding unique tracking numbers for smaller collection, but when it comes to large collection (say for 150k documents) it is taking more time. Please provide me the solution for speeding the process.

This is the code that I wrote.
enter image description here

How to display API data in HTML table using JS for La Liga standings?

I am trying to make a table that gets results from a football league but I cant figure out how to display it as my current code won’t work. I tried to use JSON as the Data could come in JSON. I’ve tried looking at other solutions and tried to implement them but unfortunately they still don’t work, any help would be appreciated.

Code:

fetch("https://api.football-data.org/v2/competitions/2014/standings", {
    "method": "GET",
    "headers": {
      "x-rapidapi-host": "https://www.football-data.org/",
      "x-rapidapi-key": "c57d4c72c6b0436ab0d235d1ae77ebbd"
    }
  })
  .then(response => response.json())
  .then(data => {
    const tableBody = document.querySelector('table tbody');
    const standings = data.standings[0].table;
    div.innerText = JSON.stringify(data);

    standings.forEach((team, index) => {
      const row = document.createElement('tr');

      const positionCell = document.createElement('td');
      positionCell.textContent = index + 1;
      row.appendChild(positionCell);

      const teamCell = document.createElement('td');
      teamCell.textContent = team.team.name;
      row.appendChild(teamCell);

      const playedCell = document.createElement('td');
      playedCell.textContent = team.playedGames;
      row.appendChild(playedCell);

      const wonCell = document.createElement('td');
      wonCell.textContent = team.won;
      row.appendChild(wonCell);

      const drawnCell = document.createElement('td');
      drawnCell.textContent = team.draw;
      row.appendChild(drawnCell);

      const lostCell = document.createElement('td');
      lostCell.textContent = team.lost;
      row.appendChild(lostCell);

      const pointsCell = document.createElement('td');
      pointsCell.textContent = team.points;
      row.appendChild(pointsCell);

      tableBody.appendChild(row);
    });
  })
  .catch(error => {
    console.log(`Error fetching standings data: ${error.message}`);
  });
<h1>La Liga Standings</h1>
<table>
  <thead>
    <tr>
      <th>Position</th>
      <th>Team</th>
      <th>Played</th>
      <th>Won</th>
      <th>Drawn</th>
      <th>Lost</th>
      <th>Points</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

Hello every one [closed]

Hello every one i have index page contain two tab i want if i go to draft tab and click on view button move to view page . view page contain back button i want when i click in back button back to index tab draft not tab master can anyone help me?
Regards
this is index page
this is view page

<div id="actions" class="border rounded-3 text-end mb-3 sticky py-2 px-2"> <a asp-action="Index#tabDraft" class="btn btn-secondary btn-sm fw-bold"> Back </a> </div>
i try this didnt work

HTML form validation pattern showing error

HTML pattern form showing to match correct request format

What I have to do is make a pattern for a phone number text input
here is what I have to do

This is what i’ve tried and I keep getting this error on my page

<input type="text" name="phoneNum" size="20" title="(+971)NNNNNNNNNN" value="(+971)05" pattern="^[0-9]{8}$" required>

I tried adding pattern="^(+971)05[0-9]{8}$"but it would make the field not required

React-xarrows: several arrows are placed one over each other

I use react-xarrows library in my project. Arrows connect tables in diagram. In some cases there are more then one link between two tables so arrows between them “lie” on each other and we can see only one link instead of 3 or 4.
Here’s the part of my code:

const getArrows = () => {
        let arrows = [];

        diagram.areas?.map((area) => {
            area.foreignKeys?.map((link, key) => {                
                arrows.push(
                    <div >
                      <Xarrow
                        start={link.sourceTableName}
                        end={link.targetTableName}
                        path={"straight"} //
                        headShape={"arrow1"}
                        headSize={12}
                        startAnchor={"auto"}
                        endAnchor={"auto"}
                        zIndex={arrowIsShawn}
                        color={area.color}
                        strokeWidth={arrowWidth}
                        key={link.name}
                        passProps={{
                            onClick: (event) => onDeleteArrowHandler(link.name)
                        }}                        
                    />                      
                    </div>                    
                );
            });
        });
        return arrows;
    };

An array with tables I get in area.tables?.map …

I tried to render several components of Xarrow with different endAnchors, but then I see more arrows then it should be between table components.

How can I make all the arrows between same tables visible?

React: How to conditionally style dropdown options?

Im trying to change the className of choosen objects in the mapped array with another array(this.props.notPressAble). This is because i want some of the objects in the array to have another css style

handleOptions = () =>{
    let array = this.props.options.map((option, i) => 
    <a 
    key={i} 
    className={classes.dropdownoptions}>
    {option}</a>)

    for(let x = 0; x < this.props.options.length; x++)
    {
        if(this.props.notPressAble !== undefined)
        {
            for(let y = 0; y < this.props.notPressAble.length; y++)
            {
                if(x == this.props.notPressAble[y])
                {
                    console.log(array[x].props.className)
                    array[x].props.className = classes.dropdownoptionsnotpressable
                }
            }
        }
    }

    console.log(array)
    return array
}

The code below is where i implement the class for readers too get a better understanding of my problem

 <SideBarContainers name="Planering" notPressAble={[0, 6, 11]}
 options={[
     "Aktiviteter:",
     "+ Ny Aktivitet",
     "Visa Alla Öppna",
     "Visa Försenat",
     "Visa Alla Stängda",
     "Visa Alla Kategoriserat",
     "Att göra:",
     "+ Ny Att göra",
     "Visa Alla Öppna",
     "Visa Alla Stängda",
     "Visa Alla Kategoriserat",
     "Personal planering:",
     "+ Ny post",
     "Visa Alla enkel"

]} />

DND-KIT unable to make rows of table draggable and droppable

Trying to implement dnd-kit functionality for every row inside a table that is rendered inside of a modal.

I am trying to make the row that is created with map() method draggable and droppable inside the table. I have also created two simple components just to check if the dnd-kit is working at all and it does. But in that example I am just mapping over state that contains strings so the items prop that <SortableContext> is asking for is easy to pass. I am not sure if that is what is causing the problem in my app. If anyone can give me any suggestions or solution I would be very grateful!

This is the sortable item from the simple example that works:

import { useSortable } from "@dnd-kit/sortable";
import {CSS} from "@dnd-kit/utilities";

import Box from '@mui/material/Box';

function SortableItem(props) {

    const { 
      attributes,
      listeners,
      setNodeRef,
      transform,
      transition
    } = useSortable({id: props.id});

    const style = {
        transform: CSS.Transform.toString(transform),
        transition
    }
    return (
      <div ref={setNodeRef} style={style} {...attributes} {...listeners}>
          <Box sx={{margin: "5px", border: "1px solid gray"}}>
          <button>button</button>
              {props.id}
          </Box>
      </div>
        )
};

export default SortableItem;

This is the second piece of code that creates the working example:

import {useState} from 'react';
import Box from '@mui/material/Box';
import { DndContext, closestCenter } from "@dnd-kit/core";
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";
import SortableItem from "./sortableItem.js";

function DndKitTest() {
    const [people, setPeople] = useState(["Luka Jovicic", "Dejan Markic", "Branko Kovacevic", "Nemanja Djokic"]);

  return (
    <DndContext
      collisionDetection={closestCenter}
      onDragEnd={handleDragEnd}
    >
    <Box sx={{ padding: "5px", witdh: 10, border: "1px solid gray", margin: 5 }}>
      <h3>List of people!</h3>
      <SortableContext
        items={people}
        strategy={verticalListSortingStrategy}
      > 
       {people.map(person => <SortableItem key={person} id={person} />)}
      </SortableContext>
    </Box>
    </DndContext>
    );

    function handleDragEnd(event) {
        console.log("Drag end called");
        const {active, over} = event;
        console.log("ACTIVE: " + active.id);
        console.log("OVER: " + over.id);

        if(active.id !== over.id) {
           setPeople((items) => {
            const activeIndex = items.indexOf(active.id);
            const overIndex = items.indexOf(over.id);

            return arrayMove(items, activeIndex, overIndex)
           });
        }
    }
}

export default DndKitTest;

As for my APP I will provide two pieces of code that are using dnd-kit:

import React, { useMemo, Fragment, useState, useEffect } from 'react';
import TableRow from '@mui/material/TableRow';
import TableCell from '@mui/material/TableCell';
import IconButton from '@mui/material/IconButton';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import Button from '@mui/material/Button';
import Box from '@mui/material/Box';
import CloseOutlinedIcon from '@mui/icons-material/CloseOutlined';
import { useSortable } from "@dnd-kit/sortable";
import { CSS } from "@dnd-kit/utilities";

function SortingRow({ sortOrder, fields, moveRowUp, moveRowDown, handleOrderChange, resetSingleSort, rowItems, setRowItems, handleRowsChange }) {

     const [idVal, setIdVal] = useState("");

    const rows = sortOrder.map((item, index) => {
    const ID = `sortable-row-${index}`;
    const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id: ID });
    const style = {
      transform: CSS.Transform.toString(transform),
      transition
    };

    useEffect(() => {
      setIdVal(ID);
    }, [ID]);

    return (
      <TableRow key={index} ref={setNodeRef} style={style} {...attributes} {...listeners}>
        <TableCell>
          {fields.find((f) => f.name === item.field)?.label}
          <IconButton onClick={() => moveRowUp(item.field)}>
            <ArrowUpwardIcon />
          </IconButton>
          <IconButton onClick={() => moveRowDown(item.field)}>
            <ArrowDownwardIcon />
          </IconButton>
        </TableCell>
        <TableCell>
          <Box>
            <Button onClick={() => handleOrderChange(item.field, item.direction)}>
              {item.direction}
            </Button>
            <IconButton onClick={() => resetSingleSort(item.field)}>
              <CloseOutlinedIcon />
            </IconButton>
          </Box>
        </TableCell>
      </TableRow>
    );
  });

useEffect(() => {
handleRowsChange(rows, idVal);
}, []);

// console.log('CEO ROW IZ sortingROW', rows);
// console.log('ID IZ sortingROW', id);
// console.log('STATE ID IZ sortingRow', idVal);

  return <>{rows}</>;
}

export default SortingRow;

And the second one:

import React, { useState, useMemo } from 'react';
import PropTypes from 'prop-types';

import Table from '@mui/material/Table';
import TableBody from '@mui/material/TableBody';
import TableCell from '@mui/material/TableCell';
import TableHead from '@mui/material/TableHead';
import TableRow from '@mui/material/TableRow';
import Paper from '@mui/material/Paper';
import IconButton from '@mui/material/IconButton';
import Button from '@mui/material/Button';
import CloseOutlinedIcon from '@mui/icons-material/CloseOutlined';
import Box from '@mui/material/Box';
import ArrowUpwardIcon from '@mui/icons-material/ArrowUpward';
import ArrowDownwardIcon from '@mui/icons-material/ArrowDownward';
import { DndContext, closestCenter } from "@dnd-kit/core";
import { arrayMove, SortableContext, verticalListSortingStrategy } from "@dnd-kit/sortable";

import SortingRow from "./sortingRow.js";

function TableComponent({ sortOrder, setSortOrder, fields, moveRowUp, moveRowDown, handleOrderChange, resetSingleSort, onRowsUpdated, rows, id }) {

 const [rowsVal, setRowsVal] = useState([]);
 const [activeRowId, setActiveRowId] = useState("");
 const [overRowId, setOverRowId] = useState("");

 const handleRowsChange = (rows, idVal) => {
     setRowsVal(rows);
 };
     console.log("rowsVal", rowsVal);

  function handleDragEnd(event) {
    console.log("Drag end called!");
    const { active, over } = event;
    console.log("ACTIVE: " + active.id);
    console.log("OVER: " + over.id);

    setActiveRowId(active.id);
    setOverRowId(over.id);

    if (active.id !== over.id) {
      setSortOrder((items) => {
        const activeIndex = items.indexOf(active.id);
        const overIndex = items.indexOf(over.id);

        return arrayMove(items, activeIndex, overIndex);
      });
    }
  };

  return (
    <DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
      <Table sx={{ minWidth: 650 }} aria-label="simple table">
        <TableHead>
          <TableRow>
            <TableCell>Field</TableCell>
            <TableCell>Order</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          <SortableContext items={rowsVal} strategy={verticalListSortingStrategy}>
            <SortingRow
              sortOrder={sortOrder}
              fields={fields}
              moveRowUp={moveRowUp}
              moveRowDown={moveRowDown}
              handleOrderChange={handleOrderChange}
              resetSingleSort={resetSingleSort}
              handleRowsChange={handleRowsChange}
              activeRowId={activeRowId}
              overRowId={overRowId}
            />
          </SortableContext>
        </TableBody>
      </Table>
    </DndContext>
  );
}

TableComponent.propTypes = {
  sortOrder: PropTypes.array.isRequired,
  fields: PropTypes.array.isRequired,
  moveRowUp: PropTypes.func.isRequired,
  moveRowDown: PropTypes.func.isRequired,
  handleOrderChange: PropTypes.func.isRequired,
  resetSingleSort: PropTypes.func.isRequired,
};

export default TableComponent;

I think that passing the items prop inside the is being passed the wrong way? Maybe all the different buttons and functions inside the SortingRow are causing the problem? I am pretty sure that ID-s are not the problem, because when I try to drag the row at index 0 over the row that is on index 1 everything console.log-s correctly.

How the value is undefined , when reading from reducer/ store in react redux?

I am working in react redux. I stored the value in reducer and try to retrieve it. Value is undefined? I am getting the sessionId from url. In App.js, sessionId is having value.

http://localhost:3000?SessionId=89e2ff80-c1d7

import * as types from '../lib/store/action';

const App = () => {
  const dispatch = useDispatch();
  useEffect(function () {

    const params = new URLSearchParams(window.location.search);
    const SessionId = params.get('SessionId');

    if (SessionId != null && SessionId.length) {
      console.log("saving SessionId: " + SessionId);
      dispatch(
        types.updateData({
          SessionId: SessionId
        })
      );
    }
 })
}

Reducer.js

import * as types from './action';

export const initialState = {

    recDetails: {
        name: '',
       country: '',
        city: ''
    },
    SessionId: ''
}

const Datareducer = (state = initialState, action) => {

    switch (action.type) {

        case types.UPDATE__DATA:

            const output = action.payload;

            if (output.recDetails) {

                state.recDetails = output.recDetails;

            }

            if (output.SessionId) {

                state.SessionId = output.SessionId;

            }

            return {

                ...state,

            }

            break;

        default:

            return state;

    }

}

 

export default Datareducer;



Component1.js

import * as types from '../../lib/store/action';

const { SessionId } = useSelector(state => state.app.DataReducer.SessionId);

  const uDispatch = useDispatch();

  useEffect(() => {

      alert(SessionId);}

SessionId is undefined.....

http://localhost:3000?SessionId=89e2ff80-c1d7

Hi, I am reading the sessionId from ur paraameter in app.js. SessionId is showing in app.js and then store in reducer. Readming sessionId in component1 is undefined.

How to retrieve profile data and edit data with service and context with react?

I have a react application and I try to retrieve the profile data in the text fields.

So I have a service:

export const AccountRequest = async (token, data) => {
    try {
        const response = await fetch("http://192.168.1.67:8000/api/user/me/", {
            method: "GET",
            headers: {
                Authorization: "Token 5dd44e266bf43435742f587f4d61b04d473d9cec",
                "Content-Type": "application/json",
            },
        });

        
        return response.data;
    } catch (error) {
        throw error;
    }
};

and a context:


import { AccountRequest, loginRequest, registerRequest } from "./authentication.service";
import React, { AsyncStorage, createContext, useState } from "react";

export const AuthContext = createContext();


export const AuthContextProvider = ({ children }) => {
    const [isLoading, setIsLoading] = useState(false);
    const [error, setError] = useState("");
    const [user, setUser] = useState(null);


    const updateUserProfile = async (data) => {
        try {           
        
            const updateAccount = await AccountRequest(data);
            console.log(updateAccount);

            // Update the user profile in the state
            setUser(updateAccount);
        } catch (error) {
            console.log("Update user profile failed:", error);
        }
    }

and the view:

export const SettingsScreen = ({ navigation }) => {
    const [email, setEmail] = useState("");
    const [username, setUsername] = useState("");
    const { updateUserProfile, user, isLoading } = useContext(AuthContext);

    return (
        <AccountBackground>
            <AccountCover />
            <Title>Instellingen</Title>
            <AccountContainer>
                <AuthInput
                    label="E-mail"
                    value={console.log(user.email)}
                    textContentType="emailAddress"
                    keyboardType="email-address"
                    autoCapitalize="none"
                    onChangeText={(u) => {
                        setEmail(u);
                    }}
                />
                <Spacer size="large">
                    <AuthInput
                        label="username"
                        value={user.username}
                        textContentType="username"
                        keyboardType="username"
                        autoCapitalize="none"
                        onChangeText={(account) => setUsername(account)}
                    />
                </Spacer>

                <Spacer size="large">
                    {!isLoading ? (
                        <AuthButton icon="email" mode="contained" onPress={() => console.log("text")}>
                            Save
                        </AuthButton>
                    ) : (
                        <ActivityIndicator animating={false} />
                    )}
                </Spacer>
            </AccountContainer>
            <Spacer size="large">
                <AuthButton mode="contained" onPress={() => navigation.goBack()}>
                    Back
                </AuthButton>
            </Spacer>
        </AccountBackground>
    );
};

and in swagger I have this api call: http://192.168.1.67:8000/api/user/me/ and it returns the correct object:

{
  "email": "[email protected]",
  "username": "user"
}

But in the view of react I get undefined in the console.log of email

Question: how to retrive the user data from the api call in the view of react?

How do I use Node.JS to run a web application?

I am learning to code and I created an application that can write a simple Human Resources letter to test how to run my Javascript code on a server, using Node. The application works on my desktop, though when using the server on local host 3000, there is no functionality to my application.

My server.js code is as follows:

const express = require("express");
const bodyParser = require("body-parser");

const app = express();

app.use(express.static("Public"));

app.use(bodyParser.urlencoded({extended: true}));

//Route 1
app.get("/test", function(req, res){
res.sendFile(__dirname + "/test.html");
});

app.get("/test", function(req, res){

var submitButton = document.querySelector(".submit");
var statement = document.querySelector(".statement");

submitButton.addEventListener("click", ()=>{
    var nameInput = document.querySelector(".name-input-field").value;
    var letterType = document.querySelector("#letterType").value;


    var textTemplate = `Dear employee, 

    I am writing this letter to you in regards to the outcome of the recent disciplinary 
    meeting that we held. 
    
    replace paragraph
    
    If you have any queries regarding the content of this letter please do not hesitate 
    to contact me.` 
    
  
    var fittedText = textTemplate.replace(/b(employee)b/ig, nameInput)


    if(letterType == "Letter of Concern"){
    fittedText = fittedText.replace(/b(replace paragraph)b/ig, `On this particular 
    occasion I have decided not to proceed with formal disciplinary action. However, 
    this letter is to be treated as confirmation that I have discussed my concerns with 
    you and that you are expected to make every effort to address the shortcomings that 
    have been identified.
  This letter is not intended to be a formal warning and does not form part of the 
  company's disciplinary procedure, however, it will be kept in your personnel file and 
  thus takes the form of what I consider to be a reasonable written management 
  instruction.`)
  }
  if(letterType == "Written Warning"){
  fittedText = fittedText.replace(/b(replace paragraph)b/ig, `At the hearing you gave 
  no satisfactory explanation for your actions. Having carefully reviewed the 
  circumstances, I have decided that a written warning is the appropriate sanction. This 
  written warning will be placed on your personnel file but will be disregarded for 
  disciplinary purposes after six months, provided your conduct improves to a 
  satisfactory level.`)
  }
  if(letterType == "Final Written Warning"){
  fittedText = fittedText.replace(/b(replace paragraph)b/ig, `Having carefully 
  reviewed the circumstances, including the severity of the offence, I have decided that 
  a first and final written warning is the appropriate sanction.
  This first and final written warning will be placed on your personnel file but will be 
  disregarded for disciplinary purposes after twelve months, provided your 
  conduct/performance improves to a satisfactory level.`)
  }
  if(letterType == "Dismissal"){
  fittedText = fittedText.replace(/b(replace paragraph)b/ig, `Having carefully 
  considered all the evidenced presented at the disciplinary hearing, I have decided to 
  terminate your contract with immediate effect.`)
  }
  
    statement.innerText = fittedText

  });

  res.send(statement.innerText);

  });

  app.listen(3000, function(){
  console.log("Server started on port 3000");
  });

And my HTML is as follows:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- <link rel="stylesheet" href="css/styles.css">-->
</head>
<body>

<div class="test-container">
<h1>Human Resources Letter</h1>
<form> 
  <label>Employee's Name:</label>
  <input class="name-input-field" type="text"></input>
  <br>
  </form>
<br>
<form> 
  <label for="letter">Letter type?</label>  
  <select name="letter" id="letterType">
      <option disabled hidden selected>Select</option>
      <option value="Letter of Concern">Letter of Concern</option>
      <option value="Written Warning">Written Warning</option>
      <option value="Final Written Warning">Final Written Warning</option>
      <option value="Dismissal">Dismissal</option>
  </select>  
  </form>
  <br>
  <button class="submit">Submit</button>
  <br>
  </div>
  <h3 class="statement"></h3>
  <p class="statement"></p>
  <!--<script src="test.js"></script>-->
  </body>
  </html>