TypeError: inject.endpoints is not a function - redux-toolkit

I was reading RTK Query Quick Start tutorial and was trying it in javascript while running it shown me this error.
Example at the corresponding site has shown both Typescript and Javascript code, but sandbox example is in typescript.
src/app/services/pokemon.js
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query/react';
export const pokemonApi = createApi({
reducerPath:'pokemonApi',
baseQuery: fetchBaseQuery({
baseUrl: 'https://pokeapi.co/api/v2'
}),
enedpoints: (builder)=>({
getPokemonByName: builder.query({
query:(name)=>`pokemon/${name}`,
}),
}),
});
export const { useGetPokemonByNameQuery } = pokemonApi
src/app.jsx
import { useGetPokemonByNameQuery } from './services/pokemon';
export default function App(){
const { data, error, isLoading } = useGetPokemonByNameQuery('bulbasaur');
return (
<div className="App">
{error ? (
<>Oh no, there was an error</>
) : isLoading ? (
<>Loading...</>
) : data ? (
<>
<h3>{data.species.name}</h3>
<img src={data.sprites.front_shiny} alt={data.species.name} />
</>
) : null}
</div>
);
}
src/app/store.js
import { configureStore } from "#reduxjs/toolkit";
import { setupListeners } from "#reduxjs/toolkit/dist/query";
import counterReducer from "../features/counter/counterSlice";
import { pokemonApi } from "../services/pokemon";
export const store = configureStore({
reducer:{
counter: counterReducer,
[pokemonApi.reducerPath]: pokemonApi.reducer,
},
middleware: (getDefaultMiddleware)=>
getDefaultMiddleware().concat(pokemonApi.middleware),
});
// optional, but required for refetchOnFocus/refetchOnReconnect behaviors
// see `setupListeners` docs - takes an optional callback as the 2nd arg for customization
setupListeners(store.dispatch)

You have a typo there. enedpoints instead of endpoints.

Had the same problem;
I had a typo on endpoints

Related

Using leaflet.markercluster with a Nuxt 3 app

I'm using Leaflet with Nuxt3, TypeScript and Composition API on a production website.
As we're getting more and more markers, I'd like to use leaflet.markercluster but I can't get how to make it work properly
Here's my setup :
leaflet.client.ts
import {
LIcon,
LMap,
LMarker,
LPopup,
LTileLayer,
} from "#vue-leaflet/vue-leaflet";
import L from "leaflet";
export default defineNuxtPlugin((nuxtApp) => {
nuxtApp.vueApp.component("LMap", LMap);
nuxtApp.vueApp.component("LTileLayer", LTileLayer);
nuxtApp.vueApp.component("LMarker", LMarker);
nuxtApp.vueApp.component("LIcon", LIcon);
nuxtApp.vueApp.component("LPopup", LPopup);
return {
provide: {
L,
},
};
});
Map.vue
<client-only>
<l-map
ref="locationsMap"
:min-zoom="leafletOptions.minZoom"
:max-zoom="leafletOptions.maxZoom"
:zoom-animation="true"
:zoom="leafletOptions.zoom"
:center="leafletOptions.center"
:useGlobalLeaflet="false"
:options="{ tap: false }"
#ready="onLeafletReady">
<l-tile-layer :url="leafletOptions.url"/>
<template v-for="location in locations"
:key="location.id">
<l-marker
:lat-lng="[location.attributes.lat, location.attributes.long]"
v-if="location.attributes.active">
<div v-if="location.attributes.lat && location.attributes.long">
<l-popup class="text-center flex flex-col gap-y-4">
...
</l-popup>
<l-icon>
...
</l-icon>
</div>
</l-marker>
</template>
</l-map>
...
</client-only>
<script setup lang="ts">
import {LIcon, LMap, LMarker, LPopup, LTileLayer} from "#vue-leaflet/vue-leaflet";
import "leaflet/dist/leaflet.css";
const leafletOptions = ref({
url: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",
minZoom: 5,
maxZoom: 13,
zoom: 5.5,
map: null,
center: [47.040182, 2.536054],
bounds: null,
overlayLocation: false,
colors: ["#ED722E", "#F6BE00", "#979B0B", "#DA2C81"],
});
// Setup and api calls to get locations
</script>
package.json
{
...,
"depencencies": {
"#vue-leaflet/vue-leaflet": "^0.7.0",
"leaflet": "^1.9.3",
"leaflet.markercluster": "^1.5.3",
},
"devDependencies": {
"nuxt": "^3.0.0",
"typescript": "^4.9.4"
"#types/leaflet.markercluster": "^1.5.1",
}
}
The thing is, now I try to group my markers by adding leaflet.markercluster. So I added something like this :
leaflet.client.ts
...
import "leaflet.markercluster";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
export default defineNuxtPlugin((nuxtApp) => {
...
return {
provide: {
L,
},
};
});
But now I don't know what to do next. Using L.markerClusterGroup() as the official documentation says does not work as we get a 500 error for using a client-side method with ssr.
I also tried to directly import in my component with import :
Map.vue
import { MarkerClusterGroup } from 'leaflet.markercluster';
const markersGroup = ref(null);
...
const onLeafletReady = async () => {
markersGroup.value = new MarkerClusterGroup() // NOT WORKING
await nextTick();
leafletObject.value = locationsMap.value;
leafletReady.value = true;
leafletObject.value.addLayer(markersGroup.value)
}
But we got the same problem as using L.anyMethod() by getting a 500 error.
I saw that Sam85 on this question has the package installed, but that was not the same problem. :/
Has anyone ever tried to make it work with Nuxt 3 ?

React-testing-library with Ionic v5 (react) and react-hook-form- change events do not fire

I am trying to test a component rendered with Controller from react-hook-form with react-testing-library
<Controller
render={({ onChange, onBlur, value }) => (
<IonInput
onIonChange={onChange}
onIonBlur={onBlur}
value={value}
type="text"
data-testid="firstname-field"
/>
)}
name="firstName"
control={control}
defaultValue={firstName}
/>
Default values are as expected when I render the component with a some mock data. However, when I go about changing values, it seems the events are not firing. From this blog post it looks like ionic exports a set of test utils to handle ionic's custom events. After setting that up in my setupTests.ts I'm attempting to use both the ionFireEvent and the fireEvent from RTU, neither of which reflect changes in the component when I use debug(). I've set it up so I can use both fireEvent and ionFireEvent to test:
import { render, screen, wait, fireEvent } from "#testing-library/react";
import { ionFireEvent } from "#ionic/react-test-utils";
// using RTL fireEvent - no change
it("fires change event on firstname", () => {
const { baseElement } = renderGolferContext(mockGolfer);
const firstNameField = screen.getByTestId("firstname-field") as HTMLInputElement;
fireEvent.change(firstNameField, { target: { detail: { value: "Jill" } } });
expect(firstNameField.value).toBe("Jill");
});
// using IRTL ionFireEvent/ionChange - no change
it("fires change event on firstname", () => {
const { baseElement } = renderGolferContext(mockGolfer);
const firstNameField = screen.getByTestId("firstname-field") as HTMLInputElement;
ionFireEvent.ionChange(firstNameField, "Jill");
expect(firstNameField.value).toBe("Jill");
});
screen.debug(baseElement);
I've also tried moving the data-testid property to the controller rather than the IonInput suggested here, with the result being the same: no event is fired.
Here are the versions I'm using:
Using Ionic 5.1.1
#ionic/react-test-utils 0.0.3
jest 24.9
#testing-library/react 9.5
#testing-library/dom 6.16
Here is a repo I've created to demonstrate.
Any help would be much appreciated!
this line appears to be incorrect...
expect(firstNameField.value).toBe("Jill");
It should be looking at detail.value since that is what you set
expect((firstNameField as any).detail.value).toBe("Jill");
this is my test,
describe("RTL fireEvent on ion-input", () => {
it("change on firstname", () => {
const { baseElement, getByTestId } = render(<IonicHookForm />);
const firstNameField = screen.getByTestId(
"firstname-field"
) as HTMLInputElement;
fireEvent.change(firstNameField, {
target: { detail: { value: "Princess" } },
});
expect((firstNameField as any).detail.value).toEqual("Princess");
});
});

How to await an auth object with hooks? (MongoDB Stitch in React Native)

I am using React Native to build an app that relies on MongoDB Stitch for authentication. More often than not, the app crashes because the client object has not yet loaded when I use it in the following line of code. The error I get is the infamous TypeError: undefined is not an object followed by evaluating 'client.auth.user'.
import React from 'react';
import { View, Text } from 'react-native';
import { Stitch } from 'mongodb-stitch-react-native-sdk';
const APP_ID = '<my app ID>';
const client = Stitch.hasAppClient(APP_ID)
? Stitch.getAppClient(APP_ID)
: Stitch.initializeDefaultAppClient(APP_ID);
const { user } = client.auth;
const Home = () => {
return (
<View style={styles.home}>
<Text>HOME</Text>
<Text>Hi {user.profile.data.email}</Text>
</View>
);
};
export default Home;
const styles = {
home: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center'
}
};
The example provided with the MongoDB Stitch NPM package uses componentDidMount (see here), but I am trying to make this work using Hooks. I have tried useEffect, a bunch of if statements, async/await, placing the object in state with useState; No luck.
So yeah, you can use useEffect hook to instantiate the client and get the user info.
useEffect(() => {
_loadClient();
}, []);
const [client,setClient] = useState({});
const [user,setUser] = useState({});
_loadClient() {
Stitch.initializeDefaultAppClient('<your-client-app-id>').then(client => {
setClient(client);
if(client.auth.isLoggedIn) {
setUser( client.auth.user)
}
});
}
That should do it.

Nuxt.js - Implementing a component using Plugin

I would like to implement a custom Toaster component into my NuxtJs application by this method this.$toast.show({}) What is the best way of approaching this? Sadly I can't find any documentation on this.
Sorry, I arrive one year late...
I had the same proplem. Here is my code:
The index of my plugin (index.js ; Nofification.vue is a classical Vue component):
import Notifications from './Notifications.vue'
const NotificationStore = {
state: [], // here the notifications will be added
settings: {
overlap: false,
horizontalAlign: 'center',
type: 'info',
timeout: 5000,
...
},
setOptions(options) {
this.settings = Object.assign(this.settings, options)
},
removeNotification(timestamp) {
...
},
addNotification(notification) {
...
},
notify(notification) {
...
},
}
const NotificationsPlugin = {
install(Vue, options) {
const app = new Vue({
data: {
notificationStore: NotificationStore,
},
methods: {
notify(notification) {
this.notificationStore.notify(notification)
},
},
})
Vue.prototype.$notify = app.notify
Vue.notify = app.notify
Vue.prototype.$notifications = app.notificationStore
Vue.component('Notifications', Notifications)
if (options) {
NotificationStore.setOptions(options)
}
},
}
export default NotificationsPlugin
Here I call my plugin and inject it in Nuxt:
import Notifications from '~/components/NotificationPlugin'
Vue.use(Notifications)
export default (context, inject) => {
inject('notify', Vue.notify)
}
In my case, I use it in another plugin (nuxtjs axios).
import NOTIFICATIONS from '~/constants/notifications'
export default function ({ error, $axios, app }) {
// Using few axios helpers (https://axios.nuxtjs.org/helpers):
$axios.onError((axiosError) => {
// eslint-disable-next-line no-console
console.log('Axios: An error occured! ', axiosError, axiosError.response)
if (process.server) {
...
} else {
app.$notify({
message: 'Mon message',
timeout: NOTIFICATIONS.DEFAULT_TIMEOUT,
icon: 'tim-icons icon-spaceship',
horizontalAlign: NOTIFICATIONS.DEFAULT_ALIGN_HORIZONTAL,
verticalAlign: NOTIFICATIONS.DEFAULT_ALIGN_VERTICAL,
type: 'success',
})
console.log('PRINT ERROR')
return Promise.resolve(true)
}
})
}
As I injected it, I think I could have done export default function ({ error, $axios, app, $notify }) { and directly use $notify (and not the app.$notify).
If you want a better understanding, feel free to consult #nuxtjs/toast which works the same way:
https://github.com/nuxt-community/community-modules/blob/master/packages/toast/plugin.js
And the matching Vue component:
https://github.com/shakee93/vue-toasted/blob/master/src/index.js
Good luck, this is not easy stuff. I'll try to add something easier to understand in the docs!
you can find in this package https://www.npmjs.com/package/vue-toasted
installation
npm install vue-toasted --save
make a file as name toast.js in plugin folder
toast.js
import Vue from 'vue';
import Toasted from 'vue-toasted';
Vue.use(Toasted)
add this plugin to nuxt.config.js
plugins: [
{ src: '~/plugins/toast', ssr: false },
],
now you able to use in your methods like this
this.$toasted.show('hello i am your toast')
hope this helps

How to fetch "return Response::json(array([....,....])) " data in Vuejs

How to fetch Laravel multiple return "array" data in Vuejs
Below Laravel code is working properly.
public function show($id)
{
$model = Fabricsbooking::with(['fileno','fileno.merchandiser', 'fileno.buyer', 'items.yarncount'])
->findOrFail($id);
$yarn = Fabricsbookingitem::with('yarncount')->where('fabricsbooking_id', $id)
->groupBy('yarncount_id')
->selectRaw('sum(qty)as yarn_qty, sum(total_yarn)as total_yarn, yarncount_id' )
->get();
return Response::json(array(['model'=>$model],['yarn'=> $yarn]));
}
api.js code
import axios from 'axios'
export function get(url, params) {
return axios({
method: 'GET',
url: url,
params: params,
})
}
export function byMethod(method, url, data) {
return axios({
method: method,
url: url,
data: data
})
}
Vue template page script:
<script>
import Vue from 'vue'
import {get, byMethod} from '../../lib/api'
export default {
data:()=>{
return{
show:false,
model:{
items:[],
fileno:{},
},
yarn:{}
}
},
beforeRouteEnter(to, from, next){
get(`/fabbooking/${to.params.id}`)
.then((res)=>{
next(vm=> vm.setData(res))
})
},
beforeRouteUpdate(to, from, next){
this.show = false
get(`/fabbooking${to.params.id}`)
.then((res)=>{
this.setData(res)
next()
})
},
methods:{
setData(res){
Vue.set(this.$data, 'model', res.data.model)
this.show=true
},
deleteItem(){
byMethod('delete', `/fabbooking/${this.model.id}`)
.then((res)=> {
if (res.data.deleted){
this.$router.push('/fabook')
}
})
}
},
}
</script>
When load the page in browser, shown below error code in Console
"app.js:682[Vue warn]: Error in render: "TypeError: Cannot read property 'id' of undefined""
Need to solutions for Vue template page script.
The problem here is Cannot read property 'id' of undefined
Since the only place you use id is in to.params.id it means that params is undefined.
You can double check it with the following test:
beforeRouteEnter(to, from, next){
console.log(to.params)//like this you check params has values.
},
Maybe your route is not correctly configured. Did you forget the "props:true" flag for example?
More info in the docs: vue route params