Missing JSDoc #param "props.children" type. and Missing JSDoc #param "props.children" type. with React Native FunctionalComponents - reactjs

I'm using JSDoc & TSDoc on a react native project.
Here is the file:
import React, { createContext, useContext, FC } from 'react'
import useUserData, { UseUserDataType } from './useUserData'
import { AuthContext } from './FirebaseContextProvider'
import { AuthUser } from '../../common'
// Initial state
const initialUserDataContext = {
userData: {},
} as UseUserDataType
// Create the context objects
export const UserDataContext = createContext<UseUserDataType>(initialUserDataContext)
/**
* Context provider for user data from firebase
*
* #param props -
* #param props.children - application parts that are dependent on user data.
* #returns a context provider for user data
*/
const DataContextProvider: FC = ({ children }) => {
const { user } = useContext(AuthContext)
// UserData
const userData = useUserData(user as AuthUser)
return (
<UserDataContext.Provider value={userData}>
{children}
</UserDataContext.Provider>
)
}
export default DataContextProvider
I have two warnings:
On the second #param:
tsdoc-param-tag-with-invalid-name: The #param block should be followed by a valid parameter name: The identifier cannot non-word characterseslinttsdoc/syntax
On the begining of the JSDoc lines:
Missing JSDoc #param "props.children" type.eslintjsdoc/require-param-type
I'm not really getting how I shall document the props I guess. Any insights ?
Thanks
Edit:
If I add the types as #param {Type}, TSDoc complain because it is TypeScript:
tsdoc-param-tag-with-invalid-type: The #param block should not include a JSDoc-style '{type}'eslinttsdoc/syntax
For the time being I deleted the rules, waiting to see if there is a better configuration.
'jsdoc/require-returns-type': 'off',
'jsdoc/require-returns-type': 'off',

This might be a little old but for those who run into similar issues.
Sheraff was right in the comment so I'd like to expand.
Let's first look at the error/s:
Missing JSDoc #param "props.children" type.
So that means you are missing the parameters type.
Then:
tsdoc-param-tag-with-invalid-name: The #param block should be followed by a valid parameter name: The identifier cannot non-word characterseslinttsdoc/syntax
This means this:
* #param props.children - application parts that are dependent on user data.
Should be this without text after the param name:
* #param {Object} children
Then finally this:
tsdoc-param-tag-with-invalid-type: The #param block should not include a JSDoc-style '{type}'eslinttsdoc/syntax
This means you have added a type - {type} - which is not a recognised type.
A valid type means String, Int, Object and this is NOT because you are using TS. It's JSDoc needs them signatured.
So to fix I believe the below would do it:
/**
* Context provider for user data from firebase
*
* #param {Object} children
* #returns a context provider for user data
*/

Related

Relationship between SvelteKit PageData and ActionData for form validation

// +page.svelte
/** #type {import('./$types').PageData} */
export let data;
/** #type {import('./$types').ActionData} */
export let form;
/** #type {import("svelte/store").Writable<Entity>} */
const entity = writable(form?.entity ?? data.entity);
/** #type {import("svelte/store").Readable<ValidationResult>} */
const validations = derived(entity, e => async validate(e));
The above is the pattern I’ve come up to do form validation with SvelteKit. I bind form elements to the $entity store, regardless if it was populated from the page data or the form action. The form?.entity ?? data.entity feels a little hacky. (Or maybe just clever?)
It seems to work, but is this going to cause problems? Should I be thinking about it differently?

new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method

I cannot resolve the issue. When application loads react native throw warnings.
WARN `new NativeEventEmitter()` was called with a non-null argument without the required `addListener` method.
WARN `new NativeEventEmitter()` was called with a non-null argument without the required `removeListeners` method.
This is likely due to the newest version of react-native. A lot of libraries still haven't released a new version to handle these warnings (or errors in some case). Examples include https://github.com/react-navigation/react-navigation/issues/9882 and https://github.com/APSL/react-native-keyboard-aware-scroll-view/pull/501.
If it bothers you, you can hide the warning for now (source):
import { LogBox } from 'react-native';
LogBox.ignoreLogs(['new NativeEventEmitter']); // Ignore log notification by message
LogBox.ignoreAllLogs(); //Ignore all log notifications
I just add two function to main java module:
// Required for rn built in EventEmitter Calls.
#ReactMethod
public void addListener(String eventName) {
}
#ReactMethod
public void removeListeners(Integer count) {
}
Example: for fix warning in react-native-fs add functions to android/src/main/java/com/rnfs/RNFSManager.java file.
For Kotlin use this code:
#ReactMethod
fun addListener(type: String?) {
// Keep: Required for RN built in Event Emitter Calls.
}
#ReactMethod
fun removeListeners(type: Int?) {
// Keep: Required for RN built in Event Emitter Calls.
}
same error.
change
const eventEmitter = new NativeEventEmitter(NativeModules.CustomModule);
to
const eventEmitter = new NativeEventEmitter();
works
1- update your react-native-reanimated library to "react-native-reanimated": "2.0.0"
2- You should update the babel.config.json file and add react-native-reanimated/plugin to plugins
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
"react-native-reanimated/plugin",
],
};
This will fix your issue
In my case react-native-location-enabler was creating problem.
just added platform check and executed all the "react-native-location-enabler" specific code just for Android and not for iOS.
This solved the issue.
It is the issue related with react native reanimated library. I solve it by uninstalling the library and reinstalling it. Remove all the installation steps of react-native-reanimated library provided by
https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation.
Simply install library using command
npm install react-native-reanimated#2.3.0-beta.1
If the issue still then open project in android studio. Go to file->invalidate cache. After it all things work right.
The warning is clear. You are passing a param in a constructor that not need it.
Change this:
const eventEmitter = new NativeEventEmitter(CustomModule);
to
const eventEmitter = new NativeEventEmitter();
It's going to works.
Expo users:
Upgraded #config-plugins/react-native-ble-plx to version 5.0.0, and the warning went away.
If you're using #voximplant/react-native-foreground-service, you have to replace node_modules/#voximplant/react-native-foreground-service/index.js by
/*
* Copyright (c) 2011-2019, Zingaya, Inc. All rights reserved.
*/
'use strict';
import { NativeModules, NativeEventEmitter, Platform } from 'react-native';
const isIOS = Platform.OS === 'ios';
const isAndroid = Platform.OS === 'android';
const ForegroundServiceModule = NativeModules.VIForegroundService;
let EventEmitter;
if (isAndroid) {
EventEmitter = new NativeEventEmitter(ForegroundServiceModule);
}
/**
* #property {string} channelId - Notification channel id to display notification
* #property {number} id - Unique notification id
* #property {string} title - Notification title
* #property {string} text - Notification text
* #property {string} icon - Small icon name
* #property {number} [priority] - Priority of this notification. One of:
* 0 - PRIORITY_DEFAULT (by default),
* -1 - PRIORITY_LOW,
* -2 - PRIORITY_MIN,
* 1 - PRIORITY_HIGH,
* 2- PRIORITY_MAX
* #property {string} button - If this property exist, notification will be contain button with text as button value
*/
const NotificationConfig = {
};
/**
* #property {string} id - Unique channel ID
* #property {string} name - Notification channel name
* #property {string} [description] - Notification channel description
* #property {number} [importance] - Notification channel importance. One of:
* 1 - 'min',
* 2 - 'low' (by default),
* 3 - 'default',
* 4 - 'high',
* 5 - 'max'.
* #property {boolean} [enableVibration] - Sets whether notification posted to this channel should vibrate. False by default.
*/
const NotificationChannelConfig = {
};
class VIForegroundService {
static _serviceInstance = null;
_listeners = new Map();
/**
* #private
*/
constructor() {
if (isAndroid) {
EventEmitter.addListener('VIForegroundServiceButtonPressed', this._VIForegroundServiceButtonPressed.bind(this));
}
}
static getInstance() {
if (this._serviceInstance === null) {
this._serviceInstance = new VIForegroundService();
}
return this._serviceInstance;
}
/**
* Create notification channel for foreground service
*
* #param {NotificationChannelConfig} channelConfig - Notification channel configuration
* #return Promise
*/
async createNotificationChannel(channelConfig) {
if (isIOS) {
console.warn("ForegroundService may be used only Android platfrom.")
return;
}
return await ForegroundServiceModule.createNotificationChannel(channelConfig);
}
/**
* Start foreground service
* #param {NotificationConfig} notificationConfig - Notification config
* #return Promise
*/
async startService(notificationConfig) {
if (isIOS) {
console.warn("ForegroundService may be used only Android platfrom.")
return;
}
return await ForegroundServiceModule.startService(notificationConfig);
}
/**
* Stop foreground service
*
* #return Promise
*/
async stopService() {
if (isIOS) {
console.warn("ForegroundService may be used only Android platfrom.")
return;
}
return await ForegroundServiceModule.stopService();
}
/**
* Adds a handler to be invoked when button on notification will be pressed.
* The data arguments emitted will be passed to the handler function.
*
* #param event - Name of the event to listen to
* #param handler - Function to invoke when the specified event is emitted
*/
on(event, handler) {
if (isIOS) {
console.warn("ForegroundService may be used only Android platfrom.")
return;
}
if (!handler || !(handler instanceof Function)) {
console.warn(`ForegroundService: on: handler is not a Function`);
return;
}
if (!this._listeners.has(event)) {
this._listeners.set(event, new Set());
}
this._listeners.get(event)?.add(handler);
}
/**
* Removes the registered `handler` for the specified event.
*
* If `handler` is not provided, this function will remove all registered handlers.
*
* #param event - Name of the event to stop to listen to.
* #param handler - Handler function.
*/
off(event, handler) {
if (isIOS) {
console.warn("ForegroundService may be used only Android platfrom.")
return;
}
if (!this._listeners.has(event)) {
return;
}
if (handler && handler instanceof Function) {
this._listeners.get(event)?.delete(handler);
} else {
this._listeners.set(event, new Set());
}
}
/**
* #private
*/
_emit(event, ...args) {
const handlers = this._listeners.get(event);
if (handlers) {
handlers.forEach((handler) => handler(...args));
} else {
console.log(`[VIForegroundService]: _emit: no handlers for event: ${event}`);
}
}
/**
* #private
*/
_VIForegroundServiceButtonPressed(event) {
this._emit('VIForegroundServiceButtonPressed', event);
}
}
export default VIForegroundService;
Solution found here

Post 404 (Not Found) - Axios

I'm not sure why my post requests are not found?
I'm getting this error
Still getting this error no matter what I have tried and added to my posts im not sure if this is an axios thing or if my routes are actually incorrect please if you have any information about how to fix this or where I have gone wrong please help
xhr.js:177 POST https://enigmatic-cliffs-10818.herokuapp.com/api/user/register 404 (Not Found)
dispatchXhrRequest # xhr.js:177
xhrAdapter # xhr.js:13
dispatchRequest # dispatchRequest.js:52
I need help here is my register api with routes to allow people to register and login and ensure the user is authenticated. I have tried multiple solutions on multiple forums but It doesnt seem to fix or resolve anything
import axios from "axios";
class API {
axios;
constructor() {
this.axios = axios.create();
}
/**
* #param {String} name
* #param {String} value
*/
setHeader( name, value ) {
if( value )
this.axios.defaults.headers.common[name] = value;
else
delete this.axios.defaults.headers.common[name];
}
/**
* #param {object} userData
* #param {String} userData.email
* #param {String} userData.password
*
* #returns {Promise}
*/
register( userData ) {
console.log("------");
console.log(userData);
console.log("------");
return axios.post("/api/user/register", userData);
}
/**
* #param {object} userData
* #param {String} userData.email
* #param {String} userData.password
*
* #returns {Promise}
*/
login( userData ) {
return axios.post("/api/user/login", userData);
}
authenticated() {
return axios.post("/api/user/authenticated");
}
}
export default new API();
I haven't found a solution for my application
The cause for this 404 is in the index.js of the routes directory, when you declare router.use("/api", /* .. */) for the second time, the routes get overridden. This means, the only route associated with the /api endpoint is /addFavorite/:id.
// These are your authentication routes.
router.use("/api", require("./authentication"));
//! These are your other `api` routes.
//! But this line will override the above routes.
//api routes
router.use("/api", apiRoutes);
To solve this, move authentication.js to api directory & make the following changes in /api/index.js.
const router = require("express").Router();
const userRoutes = require("./user");
const authRoutes = require("./authentication");
router.use("/user", userRoutes);
//! Make sure to use the route as `/auth` to avoid collision,
//! since you have defined `/user/login` in the authentication module.
router.use("/auth", authRoutes);
module.exports = router;
By doing so, the authentication routes will be available at /api/auth/user/login.
Hence, you have to make authentication requests to the URL — https://enigmatic-cliffs-10818.herokuapp.com/api/auth/user/register.
fetch('http://example.com/movies.json')
.then(response => response.json())
.then(data => console.log(data));
Please use fetch function for your request.

Property 'calendar' does not exist on type 'typeof client'

I'm trying to connect my Google Calender to my React website. I've got a component called Calendar. I've used the JS tutorial from Google and I've changed it to work in Typescript. I've got the authentication and authorization already working, however fetching data from the calendar is not working. I'm getting the following error when compiling/editing.
[ts] Property 'calendar' does not exist on type 'typeof client'. Did you mean 'calendars'?
I've already downloaded the types for the gapi.client.calendar and as you can see in the image below, they are also found in the #types folder. I'm kind of stuck and I don't know how I can fix this issue..
Here is my code from my Calendar.tsx
import * as React from 'react';
import { Button } from 'semantic-ui-react'
import googleApiKey from '../googleapi-key.json';
const CLIENT_ID = googleApiKey.CLIENT_ID;
const API_KEY = googleApiKey.API_KEY;
const DISCOVERY_DOCS = ["https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest"];
const SCOPES = "https://www.googleapis.com/auth/calendar.readonly";
class Calendar extends React.Component {
constructor(props: any) {
super(props);
console.log(CLIENT_ID);
console.log(API_KEY);
this.handleClientLoad = this.handleClientLoad.bind(this);
this.handleAuthClick = this.handleAuthClick.bind(this);
this.handleSignoutClick = this.handleSignoutClick.bind(this);
this.initClient = this.initClient.bind(this);
this.updateSigninStatus = this.updateSigninStatus.bind(this);
this.listUpcomingEvents = this.listUpcomingEvents.bind(this);
}
componentDidMount() {
this.initClient();
}
public render() {
return (
<div>
<Button onClick={this.handleAuthClick}>
authorizeButton
</Button>
<Button onClick={this.handleSignoutClick}>
signoutButton
</Button>
</div>
);
}
/**
* On load, called to load the auth2 library and API client library.
*/
public handleClientLoad() {
gapi.load('client:auth2', this.initClient);
}
/**
* Sign in the user upon button click.
*/
public handleAuthClick(event: any) {
gapi.auth2.getAuthInstance().signIn();
}
/**
* Sign out the user upon button click.
*/
public handleSignoutClick(event: any) {
gapi.auth2.getAuthInstance().signOut();
}
/**
* Initializes the API client library and sets up sign-in state
* listeners.
*/
public async initClient() {
await gapi.client.init({
apiKey: API_KEY,
clientId: CLIENT_ID,
discoveryDocs: DISCOVERY_DOCS,
scope: SCOPES
})
// Listen for sign-in state changes.
gapi.auth2.getAuthInstance().isSignedIn.listen(this.updateSigninStatus);
// Handle the initial sign-in state.
this.updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
}
/**
* Called when the signed in status changes, to update the UI
* appropriately. After a sign-in, the API is called.
*/
public updateSigninStatus(isSignedIn: any) {
if (isSignedIn) {
this.listUpcomingEvents();
}
}
/**
* Print the summary and start datetime/date of the next ten events in
* the authorized user's calendar. If no events are found an
* appropriate message is printed.
*/
public listUpcomingEvents() {
console.log(gapi.client.calendar); // <--- Compile error: Does not recognize calendar
}
}
export default Calendar;
EDIT
When performing console.log(gapi.client) I can see that the client contains a calendar object (see image). But why can't I reach it in my own code?
I managed to fix my own problem. After performing console.log(gapi.client) I noticed that calender was already there, so I tried the following gapi.client['calendar'] and it worked as it should. I don't know why Typescript does not recognize the calendar in the first place, so if anybody has an idea feel free to leave a comment.
Try the following
Install types npm i #types/gapi.client.calendar
Include https://apis.google.com/js/api.js & https://apis.google.com/js/platform.js in index.html
Add the following inside types in tsconfig.app.json
"types": [
"gapi",
"gapi.auth2",
"gapi.client",
"gapi.client.calendar"
]
You have to add:
"types": ["gapi", "gapi.auth2", "gapi.client", "gapi.client.calendar"]
in tsconfig.app.js and in tsconfig.json.

Redux observable - resolving multiple actions - async

I'm trying to inject a third party script onto a page and once its loaded initialise a video player.
I want to be able to have multiple video players on any page so I have some logic to check whether the script is already loaded and fire a different actions depending on whether it is or not.
My "script loading" helper looks like this:
/**
* injectScript - Inject player script into page
* #param {String} id - script tag id
* #param {String} src - script src
* #return {Promise} - script load callback
*/
injectScript (id, src) {
return new Promise(resolve => {
if (!document.getElementById(id)) {
const script = document.createElement('script');
script.setAttribute('id', id);
script.type = 'text/javascript';
script.src = src;
document.body.appendChild(script);
script.onload = () => resolve('script-loaded');
} else {
resolve('script-exists');
}
});
}
I then have an epic which calls this helper and fires an action depending on the outcome. The epic looks like this:
/**
* loadPlayerScript
* #param {Object} action$ - action observable
* #param {Object} store - redux store
* #param {Object} dependencies - injected dependencies
* #return {Object} - action observable
*/
export default function loadPlayerScript (action$, store, { scriptLoaderHelper }) {
return action$.ofType(PLAYER_SCRIPT_LOAD)
.switchMap(action => Observable.fromPromise(scriptLoaderHelper.injectScript(action.data.id, action.data.script)))
.map(data => {
if (data === 'script-loaded') {
return playerScriptSuccess();
}
return playerScriptExists();
})
.catch(error => Observable.of(playerScriptFailure(error)));
}
The problem:
The PLAYER_SCRIPT_LOAD gets fired twice (I can validate this in Redux dev tools), this is expected. Whats happening though is the epic is only resolving the promise once (and it only fires one of the actions in the map). How do I get the epic to fire the actions for each promise resolve?
I'm sure its something super simple that I'm overlooking but any helps is appreciated!
Change switchMap to mergeMap to avoid cancellation:
The main difference between switchMap and other flattening operators is the cancelling effect. On each emission the previous inner observable (the result of the function you supplied) is cancelled and the new observable is subscribed. You can remember this by the phrase switch to a new observable.
source: https://www.learnrxjs.io/operators/transformation/switchmap.html

Resources