select all checkbox inside vuetify select not working with composition API - vue.js

I am trying to add a select all checkbox inside v-select. It's working fine with options API in vue js. But when working with composition API, couldn't find a way to workable it yet. My attempt is as below.
setup() {
const fruits = ['Apples', 'Apricots', 'Avocado', 'Bananas']
let selectedFruits = []
const likesAllFruit = computed(() => {
return selectedFruits.length === fruits.length
})
const likesSomeFruit = computed(() => {
return selectedFruits.length > 0 && !likesAllFruit.value
})
const icon = computed(() => {
if (likesAllFruit.value) return 'mdi-close-box'
if (likesSomeFruit.value) return 'mdi-minus-box'
return 'mdi-checkbox-blank-outline'
})
const toggle = async () => {
if (likesAllFruit.value) {
selectedFruits = []
} else {
selectedFruits = fruits.slice()
}
await nextTick()
}
return {
fruits,
selectedFruits,
likesAllFruit,
likesSomeFruit,
icon,
toggle,
}
},
I used https://vuetifyjs.com/en/components/selects/#append-and-prepend-item to build this as per in the document. Anyone knows where I was wrong this with in composition API?
(I am using vue js 2 version with composition API plugging)

Below way works.
setup() {
const fruits = ref([
{ text: 'Apples', value: 'Apples' },
{ text: 'Apricots', value: 'Apricots' },
{ text: 'Avocado', value: 'Avocado' },
{ text: 'Bananas', value: 'Bananas' },
])
let selectedFruits = ref([{}])
const likesAllFruit = computed(() => {
return selectedFruits.value.length === fruits.value.length
})
const likesSomeFruit = computed(() => {
return selectedFruits.value.length > 0 && !likesAllFruit.value
})
const icon = computed(() => {
if (likesAllFruit.value) return 'mdi-close-box'
if (likesSomeFruit.value) return 'mdi-minus-box'
return 'mdi-checkbox-blank-outline'
})
const toggle = async () => {
if (likesAllFruit.value) {
selectedFruits.value = []
} else {
selectedFruits.value = fruits.value.slice()
}
await nextTick()
}
return {
fruits,
selectedFruits,
likesAllFruit,
likesSomeFruit,
icon,
toggle,
}
},
Thanks all!!!

Related

how to reset navigation addListener when a state is changed

I want to reset navigation addListener when state is changed but It's not working
useEffect(() => {
const {page, pageIdx, tab} = pageInfo
const remove = navigation.addListener('state', ({data:{state:{routes, index}}}) => {
if(routes[index].name === name){
if(pageIdx)
getMatchItem(`usr/goods/match/buy/history/${tab}/${page}`)
else
getItem(`usr/goods/auction/bid/${tab}/${page}`)
}
return () => remove()
})
}, [pageInfo])
so I tried to return remove function when state is changed but It couldn't work
For example:
const [stateChanged, setStateChaged] = useState(false)
const [listener, setListener] = useState(null)
useEffect(() => {
if(stateChanged && listener) {
listener()
setListener(null)
}
}, [stateChanged])
useEffect(() => {
const {page, pageIdx, tab} = pageInfo
const remove = navigation.addListener('state', ({data: {state: {routes, index}}}) => {
if (routes[index].name === name) {
if (pageIdx)
getMatchItem(`usr/goods/match/buy/history/${tab}/${page}`)
else
getItem(`usr/goods/auction/bid/${tab}/${page}`)
setStateChaged(true)
}
})
setListener(remove)
}, [pageInfo])

Reference error: can't find variable: error

the error
this is the error I'm getting when I run npx react-native run-android
I was writing the code and everything was fine till I decided to take a break then I came back and wanted to continue but this error came up so I'm not even sure where the error is from, so any help would be appreciated
I tried these fixes
react-native link (i usually do this after install a dependency or package then restart)
./gradlew clean
npm install
I'm using an older version following this video youtube
These are the only places error is used in my code
I'm trying to fetch market data from coingecko
marketReducer.js
import { ActionSheetIOS } from 'react-native';
import * as marketActions from './marketActions';
const initialState = {
myHoldings: [],
coins: [],
error: null,
loading: false
}
const marketReducer = (state = initialState, action) => {
switch (action.type) {
case marketActions.GET_HOLDINGS_BEGIN:
return {
...state,
loading: true
}
case marketActions.GET_HOLDINGS_SUCCESS:
return {
...state,
myHoldings: action.payload.myHoldings
}
case marketActions.GET_HOLDINGS_FAILURE:
return {
...state,
error: action.payload.error
}
case marketActions.GET_COIN_MARKET_BEGIN:
return {
...state,
loading: true
}
case marketActions.GET_COIN_MARKET_SUCCESS:
return {
...state,
coins: action.payload.coins
}
case marketActions.GET_COIN_MARKET_FAILURE:
return {
...state,
error: action.payload.error
}
default:
return state
}
}
marketActions.js
import axios from "axios";
export const GET_HOLDINGS_BEGIN = "GET_HOLDINGS_BEGIN"
export const GET_HOLDINGS_SUCCESS = "GET_HOLDINGS_SUCCESS"
export const GET_HOLDINGS_FAILURE = "GET_HOLDINGS_FAILURE"
export const GET_COIN_MARKET_BEGIN = "GET_COIN_MARKET_BEGIN"
export const GET_COIN_MARKET_SUCCESS = "GET_COIN_MARKET_SUCCESS"
export const GET_COIN_MARKET_FAILURE = "GET_COIN_MARKET_FAILURE"
//Holding / My Holdings
export const getHoldingsBegin = () => ({
type: GET_HOLDINGS_BEGIN
})
export const getHoldingsSuccess = (myHoldings) => ({
type: GET_HOLDINGS_SUCCESS,
payload: { myHoldings }
});
export const getHoldingsFailure = (error) = ({
type: GET_HOLDINGS_FAILURE,
payload: { error }
})
export function getHoldings(holdings = [], currency = "usd", orderBy = "market_cap_desc", sparkline = true, priceChangePerc = "7d", perPage = 10, page = 1) {
return dispatch => {
dispatch(getHoldingsBegin())
let ids = holdings.map((item) => { return item.id }).join(",");
let apiUrl = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency}&order=${orderBy}&per_page=${perPage}&page=${page}&sparkline=${sparkline}&price_change_percentage=${priceChangePerc}&ids=${ids}`
return axios({
url: apiUrl,
method: 'GET',
header: {
Accept: "application/json"
}
}).then((response) => {
console.log("GetHoldings")
console.log(response)
if (response.state == 200) {
//Massage data
let myHoldings = response.data.map((item) => {
//Retrieve our current holdings -> current quantity
let coin = holdings.find(a => a.id == item.id)
//Price from 7 days ago
let price7d = item.current_price / (1 + item.price_change_percentage_7d_in_currency * 0.01)
return {
id: item.id,
symbol: item.symbol,
name: item.name,
img: item.image,
current_price: item.current_price,
price_change_percentage_7d_in_currency: item.price_change_percentage_7d_in_currency,
holding_value_change_7d: (item.current_price - price7d) * coin.qty,
sparkline_in_7d: {
value: item.sparkline_in_7d.price.map((price) => {
return price * coin.qty
})
}
}
})
dispatch(getHoldingsSuccess(myHoldings))
} else {
dispatch(getHoldingsFailure(response.data));
}
}).catch((error) => { dispatch(getHoldingsFailure(error)); });
}
}
// Coin Market
export const getCoinMarketBegin = () => ({
type: GET_COIN_MARKET_BEGIN
})
export const getCoinMarketSuccess = (coins) => ({
type: GET_COIN_MARKET_SUCCESS,
payload: { coins }
})
export const getCoinMarketFailure = (error) => ({
type: GET_COIN_MARKET_FAILURE,
payload: { error }
})
export function getCoinMarket(currency = "usd", orderBy = "market_cap_desc", sparkline = true, priceChangePerc = "7d", perPage = 10, page = 1) {
return dispatch => {
dispatch(getCoinMarketBegin())
let apiUrl = `https://api.coingecko.com/api/v3/coins/markets?vs_currency=${currency}&order=${orderBy}&per_page=${perPage}&page=${page}&sparkline=${sparkline}&price_change_percentage=${priceChangePerc}
`
return axios({
url: apiUrl,
method: 'GET',
header: {
Accept: 'application/json'
}
}).then((response) => {
if (response.state == 200) {
dispatch(getCoinMarketSuccess(response.data))
}else{
dispatch(getCoinMarketFailure(response.data))
}
}).catch((error) => {
dispatch(getCoinMarketFailure(error))
})
}
}

How to re-run useQuery and FlatList?

I use FlatList with useState.
const [state, setState] = useState(route);
<FlatList
keyboardDismissMode={true}
showsVerticalScrollIndicator={false}
data={state}
keyExtractor={(comment) => "" + comment.id}
renderItem={renderComment}
/>
When I change the datㅁ which is contained in state, I want to re-run Flatlist with new data.
So after I mutate my data, I try to rerun useQuery first in order to change state. I put refetch module here.
1)
const { data: updatePhoto, refetch } = useQuery(SEE_PHOTO_QUERY, {
variables: {
id: route?.params?.photoId,
},
});
If I put button, this onValid function will executed.
<ConfirmButton onPress={handleSubmit(onValid)}>
onValid function changes data and after all finished, as you can see I put refetch().
=> all this process is for that if I add comment and press confirm button, UI (flatlist) should be changed.
const onValid = async ({ comments }) => {
await createCommentMutation({
variables: {
photoId: route?.params?.photoId,
payload: comments,
},
});
await refetch();
console.log(updatePhoto);
};
But when I console.log data after all, it doesnt' contain added data..
what is the problem here?
If you need more explanation, I can answer in real time.
please help me.
add full code
export default function Comments({ route }) {
const { data: userData } = useMe();
const { register, handleSubmit, setValue, getValues } = useForm();
const [state, setState] = useState(route);
const [update, setUpdate] = useState(false);
const navigation = useNavigation();
useEffect(() => {
setState(route?.params?.comments);
}, [state, route]);
const renderComment = ({ item: comments }) => {
return <CommentRow comments={comments} photoId={route?.params?.photoId} />;
};
const { data: updatePhoto, refetch } = useQuery(SEE_PHOTO_QUERY, {
variables: {
id: route?.params?.photoId,
},
});
const createCommentUpdate = (cache, result) => {
const { comments } = getValues();
const {
data: {
createComment: { ok, id, error },
},
} = result;
if (ok) {
const newComment = {
__typename: "Comment",
createdAt: Date.now() + "",
id,
isMine: true,
payload: comments,
user: {
__typename: "User",
avatar: userData?.me?.avatar,
username: userData?.me?.username,
},
};
const newCacheComment = cache.writeFragment({
data: newComment,
fragment: gql`
fragment BSName on Comment {
id
createdAt
isMine
payload
user {
username
avatar
}
}
`,
});
cache.modify({
id: `Photo:${route?.params?.photoId}`,
fields: {
comments(prev) {
return [...prev, newCacheComment];
},
commentNumber(prev) {
return prev + 1;
},
},
});
}
};
const [createCommentMutation] = useMutation(CREATE_COMMENT_MUTATION, {
update: createCommentUpdate,
});
const onValid = async ({ comments }) => {
await createCommentMutation({
variables: {
photoId: route?.params?.photoId,
payload: comments,
},
});
await refetch();
console.log(updatePhoto);
};

Why can't I use dragula in Vue3 setup but mounted?

When I use dragula in vue3 setup. It isn't working. Like this:
setup() {
const dragFrom = ref(null);
const dragTo = ref(null);
onMounted(() => {
dragula([dragFrom, dragTo], {
copy: (el) => {
console.log(el);
return true;
},
accepts: () => {
return true;
},
});
});
return { dragFrom, dragTo };
}
But this way can be successful:
mounted() {
const dragFrom = this.$refs.dragFrom;
const dragTo = this.$refs.dragTo;
dragula([dragFrom, dragTo], {
copy: function (el, source) {
console.log(el);
return true;
},
accepts: function (el, target) {
return true;
},
});
}
Both methods are based on vue3.What's wrong?
Your issue comes from the fact that you are not accessing the value of the ref, i.e. dragFrom.value and dragTo.value when passing them into the dragula() function. Remember that when you create a reactive and mutable ref object, you will need to access its inner value using the .value property.
This should therefore work:
setup() {
const dragFrom = ref(null);
const dragTo = ref(null);
onMounted(() => {
// Ensure you access the VALUE of the ref!
dragula([dragFrom.value, dragTo.value], {
copy: (el) => {
console.log(el);
return true;
},
accepts: () => {
return true;
},
});
});
return { dragFrom, dragTo };
}
See proof-of-concept on this demo CodeSandbox I've created: https://uwgri.csb.app/

Relay Moder - Pagination

I am already working on Pagination.
I used PaginationContainer for that. It work’s but no way what I am looking for.
I got button next which call props.relay.loadMore(2) function. So when I click on this button it will call query and add me 2 more items to list. It works like load more. But I would like instead of add these two new items to list, replace the old item with new.
I try to use this getFragmentVariables for modifying variables for reading from the store but it’s not working.
Have somebody Idea or implemented something similar before?
class QueuesBookingsList extends Component {
props: Props;
handleLoadMore = () => {
const { hasMore, isLoading, loadMore } = this.props.relay;
console.log('hasMore', hasMore());
if (!hasMore() || isLoading()) {
return;
}
this.setState({ isLoading });
loadMore(1, () => {
this.setState({ isLoading: false });
});
};
getItems = () => {
const edges = idx(this.props, _ => _.data.queuesBookings.edges) || [];
return edges.map(edge => edge && edge.node);
};
getItemUrl = ({ bid }: { bid: number }) => getDetailUrlWithId(BOOKING, bid);
render() {
return (
<div>
<button onClick={this.handleLoadMore}>TEST</button>
<GenericList
displayValue={'bid'}
items={this.getItems()}
itemUrl={this.getItemUrl}
emptyText="No matching booking found"
/>
</div>
);
}
}
export default createPaginationContainer(
QueuesBookingsList,
{
data: graphql`
fragment QueuesBookingsList_data on RootQuery {
queuesBookings(first: $count, after: $after, queueId: $queueId)
#connection(
key: "QueuesBookingsList_queuesBookings"
filters: ["queueId"]
) {
edges {
cursor
node {
id
bid
url
}
}
pageInfo {
endCursor
hasNextPage
}
}
}
`,
},
{
direction: 'forward',
query: graphql`
query QueuesBookingsListQuery(
$count: Int!
$after: String
$queueId: ID
) {
...QueuesBookingsList_data
}
`,
getConnectionFromProps(props) {
return props.data && props.data.queuesBookings;
},
getFragmentVariables(prevVars, totalCount) {
console.log({ prevVars });
return {
...prevVars,
count: totalCount,
};
},
getVariables(props, variables, fragmentVariables) {
return {
count: variables.count,
after: variables.cursor,
queueId: fragmentVariables.queueId,
};
},
},
);
As I figure out, there are two solutions, use refechConnection method for Pagination Container or use Refech Container.