Vue3 Pinia action is not being called - vuejs3

I am trying to setup a store using Pinia in vue3 with apollo client and composition API.
here is my store
import { defineStore } from "pinia";
import apolloClient from "../apollo.provider";
import { ALL_POSTS } from '#/constants/blog'
export const usePostsStore = defineStore("posts", {
state: () => ({
posts: []
}),
actions: {
async AllPosts() {
const { data } = await apolloClient.query({
query: ALL_POSTS,
fetchPolicy: 'no-cache'
})
console.log(data)
this.posts = data.posts.data
},
},
})
and here is the response
{
"data": {
"posts": {
"data": [
{
"id": 2
},
{
"id": 3
},
{
"id": 5
},
{
"id": 4
},
{
"id": 1
}
]
}
}
}
I get an empty array with this setup. Please help me understand how to get the posts!

Related

ReduxToolKit | CreateEntityAdaptor userSelectors.selectAll giving Cannot read properties of undefined (reading 'map')

Hi i am using ReduxToolKit CreateEntityAdaptor for crud, when i get all users from API by using userSelectors.selectAll, it gives "Cannot read properties of undefined (reading 'map')".
let me show my API response.
{
"data": [
{
"id": 16,
"name": "Admin",
"email": "admin#admin.com",
"assigned_roles": [
"Administrator"
],
"created_at": "2022-10-06T20:08:32.000000Z"
}
],
"links": {
"first": "http://laravel-api.test/api/users?page=1",
"last": "http://laravel-api.test/api/users?page=1",
"prev": null,
"next": null
},
"meta": {
"current_page": 1,
"from": 1,
"last_page": 1,
"links": [
{
"url": null,
"label": "« Previous",
"active": false
},
{
"url": "http://laravel-api.test/api/users?page=1",
"label": "1",
"active": true
},
{
"url": null,
"label": "Next »",
"active": false
}
],
"path": "http://laravel-api.test/api/users",
"per_page": 15,
"to": 1,
"total": 1
}
}
using AsyncThunk for getting data from API services/userService file
import { createAsyncThunk} from "#reduxjs/toolkit";
import axios from "axios";
import { API_URL, ACCESS_TOKEN } from "../constants";
export const fetchUsers = createAsyncThunk(
'user/fetchUsers',
async (page) => {
const data = await axios(API_URL+'/users?page='+page,
{ method:'GET',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${ACCESS_TOKEN}`
},
});
return data.data;
}
)
features/userSlice.js
import { createSlice, createEntityAdapter } from "#reduxjs/toolkit";
import { HTTP_STATUS } from "../constants";
import { fetchUsers } from "../services/userService";
const userAdapter = createEntityAdapter({
selectId: (user) => user.id,
});
const userSlice = createSlice({
name: "user",
initialState: {
loading: false,
status: null,
message: "",
},
reducers:{
pageByNumber: (state,{payload}) => {
state.page = payload.page
},
nextPage: (state, {payload}) => {
state.page = state.page++
},
previousPage: (state, {payload}) => {
state.page = state.page--
},
clear: (state) => {
state.status = null
state.message = null
}
},
extraReducers: {
[fetchUsers.pending]: (state, action) => {
state.loading = true
state.status = HTTP_STATUS.PENDING
},
[fetchUsers.fulfilled]: (state, { payload }) => {
console.log(payload.data);
state.loading = false
state.page = payload.meta.current_page
state.total_pages = Math.ceil(payload.meta.total/payload.meta.per_page)
userAdapter.setAll(state, payload.data)
state.status = HTTP_STATUS.FULFILLED
},
[fetchUsers.rejected]: (state, { payload }) => {
state.loading = false
state.status = HTTP_STATUS.REJECTED
},
},
});
export const userSelectors = userAdapter.getSelectors(
(state) => state.user
)
export const {pageByNumber, nextPage, previousPage,clear} = userSlice.actions
export default userSlice.reducer
views/users/index.js
i am not getting understand why there is map array error.
Hi i got the answer actually i had not passed my initial state to create Entity Adapter, below i have shown latest code for initial state.
initialState: userAdapter.getInitialState({ //Initial state should be wrapped in Adapter
loading: false,
status: null,
message: "",
}),

Getting a fetch error using redux toolkit and RTK-Query

I am using RTK-Query, and Redux-toolkit for this app, and I created an api-slice with createApi, as per the docs.
When I run a request to the backend, I get a "FETCH_ERROR"; however, when I run the same request using Axios, I get the data correctly from the backend, which leads me to believe I have an error in my code. I am just not sure where exactly it is.
Here is the error:
Object {
"api": Object {
"config": Object {
"focused": true,
"keepUnusedDataFor": 60,
"middlewareRegistered": true,
"online": true,
"reducerPath": "api",
"refetchOnFocus": false,
"refetchOnMountOrArgChange": false,
"refetchOnReconnect": false,
},
"mutations": Object {},
"provided": Object {},
"queries": Object {
"test(undefined)": Object {
"endpointName": "test",
"error": Object {
"error": "TypeError: Network request failed",
"status": "FETCH_ERROR",
},
"requestId": "BWOuLpOxoDKTzlUYFLW4x",
"startedTimeStamp": 1643667104869,
"status": "rejected",
},
},
"subscriptions": Object {
"test(undefined)": Object {
"QJSCV641RznGWyudGWuMb": Object {
"pollingInterval": 0,
"refetchOnFocus": undefined,
"refetchOnReconnect": undefined,
},
},
},
},
"test": Object {
"data": Array [],
},
}
Here is the test slice:
import { createSlice } from "#reduxjs/toolkit";
const testSlice = createSlice({
name: "test",
initialState: {
data: [],
},
reducers: {
getData: (state) => {
state;
},
},
});
export const { getData } = testSlice.actions;
export default testSlice.reducer;
Here is the apiSlice:
import { createApi, fetchBaseQuery } from "#reduxjs/toolkit/query/react";
export const apiSice = createApi({
reducerPath: "test",
baseQuery: fetchBaseQuery({ baseUrl: process.env.REACT_APP_backend_url }),
endpoints: (builder) => ({
test: builder.query({
query: () => "/test",
}),
}),
});
export const { useTestQuery } = apiSice;
I solved it by changing the backend URL to my current ipv4 (for expo development, otherwise just your whatever your backend URL is) address in my .env file, then deleting cache, and restarting my app. In my case I was using expo so, expo r -c, and it worked.

Normalizr with Redux with nested array of objects

I'm just getting started with using normalizr with Redux, and I can't make it work. Even though I can do it with plain JavaScript.
I have an array of objects
const data = [
{
data_detail: [
{
category: 'newCategory',
_id: '123',
},
],
_id: 'abc_id',
customer: {
_id: '456',
email: 'hello#gmail.com',
name: 'Bob',
},
date: '2021-01-10T01:51:24.387Z',
},
];
And I need to transform it to
const normalizedResponse = {
customers: {
'456': {
_id: '456',
email: 'hello#gmail.com',
name: 'Bob',
},
},
details: {
'123': {
category: 'newCategory',
_id: '123',
},
},
orders: {
'abc_id: {
order_detail: [123],
_id: 'abc_id',
customer: '456',
date: '2021-01-10T01:51:24.387Z',
},
},
};
Step 1: Display just orders
What I do:
const userSchema = new schema.Entity(
'orders',
);
const userListSchema = new schema.Array(userSchema);
const normalizedData = normalize(data, userListSchema);
What I get
{
"entities": {
"orders": {
"abc_id": {
"data_detail": [
{
"category": "newCategory",
"id": "123"
}
],
"id": "abc_id",
"customer": {
"id": "456",
"email": "hello#gmail.com",
"name": "Bob"
},
"date": "2021-01-10T01:51:24.387Z"
},
"abc_id-02": {
"data_detail": [
{
"category": "newCategory1",
"id": "123-02"
}
],
"id": "abc_id-02",
"customer": {
"id": "456-02",
"email": "hello#gmail.com",
"name": "Bob"
},
"date": "2001-01-10T01:51:24.387Z"
}
}
},
"result": [
"abc_id",
"abc_id-02"
]
}
What I'm trying to get:
orders: {
'abc_id: {
order_detail: [123],
_id: 'abc_id',
customer: '456',
date: '2021-01-10T01:51:24.387Z',
},
},
The question: How to remove some fields from orders and add new ones?
You have 3 different entity types in your data object. First draft out a schema for each of them:
const detail = new schema.Entity('details');
const customer = new schema.Entity('customers');
const order = new schema.Entity('orders');
Then go back and fill in the relationships. It looks like order is the outermost entity. An order contains an array of details/categories and a single customer.
const order = new schema.Entity('orders', {
data_detail: [detail],
customer,
});
All of your entities use _id instead of id, so you need to set the idAttribute.
Your data is an array of order. You can use new schema.Array(order) but you can also just use [order].
Here's your final code:
const customer = new schema.Entity("customers", {}, { idAttribute: "_id" });
const detail = new schema.Entity("details", {}, { idAttribute: "_id" });
const order = new schema.Entity(
"orders",
{
data_detail: [detail],
customer
},
{ idAttribute: "_id" }
);
const normalizedData = normalize(data, [order]);
That gives you:
{
"entities": {
"details": {
"123": {
"category": "newCategory",
"_id": "123"
}
},
"customers": {
"456": {
"_id": "456",
"email": "hello#gmail.com",
"name": "Bob"
}
},
"orders": {
"abc_id": {
"data_detail": ["123"],
"_id": "abc_id",
"customer": "456",
"date": "2021-01-10T01:51:24.387Z"
}
}
},
"result": ["abc_id"]
}

I Couldn't change HTTP headers in a NextJS project

As explained in the NextJs documentation: https://nextjs.org/docs/api-reference/next.config.js/headers , it is possible to configure the HTTP headers of a page using the code below, however my code is not working.
Next Example:
module.exports = {
async headers() {
return [
{
source: '/about',
headers: [
{
key: 'x-custom-header',
value: 'my custom header value',
},
{
key: 'x-another-custom-header',
value: 'my other custom header value',
},
],
},
]
},
}
My Code:
module.exports = {
async headers() {
return [
{
source: '/about',
headers: [
{
key: 'cache-control',
value: 'max-age=31536000',
},
],
},
]
},
}

Get outlet params from other outlet

I have the following url structure:
http://localhost:4200/foo/:fooId/(bar:barId//baz:bazId)
And the following router config:
{
path: 'foo',
children: [
{
path: ':fooId',
component: fooComponent,
children: [
{
path: ':fooId',
component: FooComponent
},
{
path: ':barId',
component: BarComponent,
outlet: 'bar'
},
{
path: ':bazId',
component: BazComponent,
outlet: 'baz'
}
]
}
]
}
If I am at http://localhost:4200/foo/0/(bar:1//baz:2), inside the BazComponent, how can I retrieve the barId parameter from the bar outlet?
import { ActivatedRoute } from '#angular/router';
params: any[] = [];
constructor(private route:ActivatedRoute) {
this.route.parent.children.forEach(children => {
this.params.push(children.snapshot.params);
});
}
ngOnInit() {
console.log(params);
}
// This returns:
// [
// { bar: barId },
// { baz: bazId }
// ]
Use this:
import {ActivatedRoute} from '#angular/router';
constructor(private route:ActivatedRoute){}
barId:number;
ngOnInit(){
// 'bar' is the name of the route parameter
this.barId = this.route.snapshot.params['bar'];
}

Resources