I want to develop a PayPal button, and following the API documentation, I have the following code:
import React, {useState}from 'react';
import {useDispatch} from 'react-redux';
import {useHistory} from 'react-router-dom';
import ReactDOM from 'react-dom';
import * as actionsReservations from '../../reservation/actions';
import {Errors} from '..';
const PayPalButton = paypal.Buttons.driver("react", { React, ReactDOM });
const PayPalReserve = ({deposit, menu, companyId, reservationDate, periodType, diners}) => {
const dispatch = useDispatch();
const history = useHistory();
const [backendErrors, setBackendErrors] = useState(null);
const createOrder = (data,actions) => {
return actions.order.create({
purchase_units:[
{
amount:{
value: deposit
},
},
],
});
};
const onApprove = (data, actions) => {
return actions.order.capture().then(response => {
dispatch(actionsReservations.reservation(
menu.id,
companyId,
reservationDate,
periodType,
diners,
response.id,
() => history.push('/reservation/reservation-completed'),
errors => setBackendErrors(errors)
));
console.log(response);
});
}
};
export default PayPalReserve;
But is throwing me the following error:
Line 9:22: 'paypal' is not defined no-undef
But if I import paypal from paypal-checkout with this line:
import paypal from 'paypal-checkout';
React throw me the following error:
"TypeError: paypal_checkout__WEBPACK_IMPORTED_MODULE_4___default.a.Buttons is undefined"
My index.html i have this in head tag:
<script defer src="https://www.paypal.com/sdk/js?client-id=MY_CLIENT_CODE"></script>
I dont know why is throwing me these errors when i don't import paypal-checkout or when I import it. If you knew how to solve it, I would appreciate it
Thanks.
Things will probably become easier for you if you simply use the official react-paypal-js package.
Here is the storybook .. copying its example:
import { PayPalScriptProvider, PayPalButtons } from "#paypal/react-paypal-js";
<PayPalScriptProvider options={{ "client-id": "test" }}>
<PayPalButtons
style={{ layout: "horizontal" }}
createOrder={(data, actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
value: "2.00",
},
},
],
});
}}
/>;
</PayPalScriptProvider>
That’s an eslint err, just add window at the beginning as PayPal is a global variable injected into the window obj
console.log(window.paypal)
Related
Learning unit-testing on the react with typescript, encountered an error when tests fall when importing axios.
screenshot error in the terminal](https://i.stack.imgur.com/dFxJU.png)
Code component
import axios from "axios";
import React, { FC, useEffect, useState } from "react";
import { IUser } from "../../types/IUsers";
const Users: FC = () => {
const [users, setUsers] = useState<IUser[]>([]);
useEffect(() => {
getUsers();
}, [users]);
const getUsers = async () => {
try {
const response = await axios.get(
"https://jsonplaceholder.typicode.com/users/"
);
const res = response.data;
setUsers(res);
} catch (error) {
console.log(error);
}
};
return (
<div data-testid="users-wrapper">
{users.map((user) => (
<div>{user.name}</div>
))}
</div>
);
};
export default Users;
Code test
import React from "react";
import { render, screen } from "#testing-library/react";
import userEvent from "#testing-library/user-event";
import Users from "./Users";
import axios from "axios";
jest.mock("axios");
describe("Testing user component", () => {
test("Show title", () => {
render(<Users />);
const usersWrapper = screen.getByTestId("users-wrapper");
expect(usersWrapper).toBeInTheDocument();
});
});
Tried install types for axios, create babel-config, create .babelrc, add `
--transformIgnorePatterns \"node_modules/(?!axios)/\""
` on the package-json. Help me please.
Add the following in package.json and try:
"jest": {
"transformIgnorePatterns": [
"node_modules/(?!axios)/"
]
},
This fixed the issue for me.
I use this pattern, and it's works for me too
I am working on a snapchat clone where I want to use the image which is cliked on webcam to store in firestore and use it as preview. The code is perfect but it's showing an error related to firebase. I have no idea what to do.
This is my code
import "./Preview.css"
import { resetCameraImage, selectCameraImage } from './../features/cameraSlice';
import { useSelector, useDispatch } from 'react-redux';
import { useHistory } from 'react-router';
import CloseIcon from "#material-ui/icons/Close";
import TextFieldsIcon from "#material-ui/icons/TextFields";
import CreateIcon from "#material-ui/icons/Create";
import NoteIcon from "#material-ui/icons/Note";
import MusicNoteIcon from "#material-ui/icons/MusicNote";
import AttachFileIcon from "#material-ui/icons/AttachFile";
import CropIcon from "#material-ui/icons/Crop";
import TimerIcon from "#material-ui/icons/Timer";
import SendIcon from "#material-ui/icons/Send";
import { v4 as uuid } from "uuid";
import { db, storage } from "./firebase";
import firebase from 'firebase';
function Preview() {
const cameraImage = useSelector(selectCameraImage);
const history = useHistory();
const dispatch = useDispatch();
useEffect(() => {
if (!cameraImage) {
history.replace('/');
}
}, [cameraImage, history]);
const closePreview = () => {
dispatch(resetCameraImage());
}
const sendPost = () => {
const id = uuid();
const uploadTask = storage.ref(`posts/${id}`).putString(cameraImage, "data_url");
uploadTask.on('state_changed', null, (error) => {
// error function
console.log(error);
},
() => {
// complete function
storage.ref('posts').child(id).getDownloadURL().then((url) => {
db.collection('posts').add({
imageUrl: url,
username: "PAPA React",
read: false,
//profilePic,
timestamp: firebase.firestore.FieldValue.serverTimestamp(),
});
history.replace('/chats');
});
}
);
};
return (
<div className="preview">
<CloseIcon className="preview__close" onClick={closePreview}/>
<div className="preview__toolbarRight">
<TextFieldsIcon />
<CreateIcon />
<NoteIcon />
<MusicNoteIcon />
<AttachFileIcon />
<CropIcon />
<TimerIcon />
</div>
<img src={cameraImage} alt="" />
<div className="preview__footer" onClick={sendPost} >
<h2>Send Now</h2>
<SendIcon fontSize="small" className="preview__sendIcon" />
</div>
</div>
)
}
export default Preview
Error thrown
My firebase rule settings
Same error on an alternate method
Same error on an alternate method
The error said the users does not have access to your Firebase Storage. Add rules for Firebase Storage to give users access. For example:
service firebase.storage {
match /b/{bucket}/o {
match /{allPaths=**} {
allow read, write;
}
}
}
I am requesting some basic info from the back end using axios but for some reason unable to render the data on screen. Below is my basic App component using hooks and a map function to return a surname
import React, { useState, useEffect } from 'react';
import FullCalendar from '#fullcalendar/react'
import dayGridPlugin from '#fullcalendar/daygrid'
import interactionPlugin from '#fullcalendar/interaction';
import { Router } from '#reach/router'
import 'bootstrap/dist/css/bootstrap.css'
import axios from 'axios'
import './custom.css'
const App = () => {
const [patients, setPatient] = useState([])
useEffect(() => {
axios.get('http://localhost:5000/api/patient').then(response => {
console.log(response.data)
setPatient(response.data)
})
}, [])
return (
<>
<div>
<ul>
{patients.map(p => (
<li>{p.surname}</li>
))}
</ul>
</div>
</>
)
}
export default App
When I check the dev tools I am bringing back all of data
I cannot see how my map function 'is not a function' can anyone help me out here please I get the below error message which is annoying
Try to use Async and Await for API call.
useEffect(function() {
async function fetchPatients() {
const response = await
fetch('http://localhost:5000/api/patient');
const json = await response.json();
setPatient(json.data);
}
fetchPatients();
}, []);
try this fixes:-
import React, { useState, useEffect } from 'react';
import FullCalendar from '#fullcalendar/react'
import dayGridPlugin from '#fullcalendar/daygrid'
import interactionPlugin from '#fullcalendar/interaction';
import { Router } from '#reach/router'
import 'bootstrap/dist/css/bootstrap.css'
import axios from 'axios'
import './custom.css'
const App = () => {
const [patients, setPatient] = useState([])
useEffect(() => {
(async () => {
try {
// fetching all patirnts
let res = await axios.get("http://localhost:5000/api/patient");
setPatient(res.data);
} catch (err) {
console.log(err);
}
})();
}, []);
return (
<>
<div>
<ul>
{patients?.map(p => (
<li>{p.surname}</li>
))}
</ul>
</div>
</>
)
}
export default App
A working code, for anyone who stupidly wastes too much time on this problem in the future. The data was nested meaning I had to setPatient to response.data.data. I was then able to pull all required info using Axios
useEffect(() => {
axios.get('http://localhost:5000/api/patient').then(response => {
setPatient(response.data.data)
})
}, [])
The following console warning has been dogging me for days...
Warning: The final argument passed to useEffect changed size between renders. The order and size of this array must remain constant. react-dom.development.js:530
Previous: [true, 1, , ]
Incoming: [false, 7, , [object Object], function () { return queryData.afterExecute({ lazy: lazy }); }, 0]
in SampleQuery (created by App)
in ApolloProvider (created by App)
in App
Warning: The final argument passed to useEffect changed size between renders. The order and size of this array must remain constant. react-dom.development.js:530
Previous: []
Incoming: [function () {
return function () { return queryData.cleanup(); };
}]
in SampleQuery (created by App)
in ApolloProvider (created by App)
in App
The code for the app is as follows...
app.tsx
import React from 'react';
import { ApolloClient } from 'apollo-client';
import { InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLink } from 'apollo-link-http';
import {ApolloProvider} from '#apollo/react-hooks';
import SampleQuery from "./sample-query";
interface AppProps {
compiler: string;
framework: string;
}
const App = (props: AppProps) => {
const cache = new InMemoryCache();
const link = new HttpLink({
uri: 'http://localhost:4000/',
});
const client = new ApolloClient({
// Provide required constructor fields
cache: cache,
link: link,
// Provide some optional constructor fields
name: 'react-web-client',
version: '1.3',
queryDeduplication: false,
defaultOptions: {
watchQuery: {
fetchPolicy: 'cache-and-network',
},
}
});
return (
<ApolloProvider client={client}>
<h1>Hello from {props.compiler} and {props.framework}!</h1>
<SampleQuery />
</ApolloProvider>
);
};
export default App;
sample-query.tsx...
import React from 'react'
import { useQuery } from '#apollo/react-hooks';
import gql from 'graphql-tag'
interface Link {
id: string;
description: string;
}
const SAMPLE_QUERY = gql`{
feed {
links {
id
description
}
}
}`;
const SampleQuery = () => {
const { loading, error, data } = useQuery(SAMPLE_QUERY);
if (loading) return <p>Loading ...</p>;
const links = (data && data.feed.links) || [];
return (<ul>
{links.map((link:Link, idx:number) => {
return (
<li key={idx}>
<span>{link.id}</span>
<span> : </span>
<span>{link.description}</span>
</li>
);
})}
</ul>)
};
export default SampleQuery;
I'm unsure why I get the warning as I'm pretty close to the examples from the React Apollo docs. Hopefully someone here has experienced this before and could point me in the right direction.
So i have this axios test and Im getting an empty div, not sure why.
test
import React from 'react';
import ReactDOM from 'react-dom';
import TestAxios from '../test_axios.js';
import {act, render, fireEvent, cleanup, waitForElement} from '#testing-library/react';
import axiosMock from "axios";
afterEach(cleanup)
it('Async axios request works', async () => {
const url = 'https://jsonplaceholder.typicode.com/posts/1'
const { getByText, getByTestId } = render(<TestAxios url={url} />);
act(() => {
axiosMock.get.mockImplementation(() => Promise.resolve({ data: {title: 'some title'} })
.then(console.log('ggg')) )
})
expect(getByText(/...Loading/i).textContent).toBe("...Loading")
const resolvedSpan = await waitForElement(() => getByTestId("title"));
expect((resolvedSpan).textContent).toBe("some title");
expect(axiosMock.get).toHaveBeenCalledTimes(1);
expect(axiosMock.get).toHaveBeenCalledWith(url);
})
the component
import React, { useState, useEffect } from 'react';
import axios from 'axios';
const TestAxios = (props) => {
const [state, setState] = useState()
useEffect(() => {
axios.get(props.url)
.then(res => setState(res.data))
}, [])
return (
<div>
<h1> Test Axios Request </h1>
{state
? <p data-testid="title">{state.title}</p>
: <p>...Loading</p>}
</div>
)
}
export default TestAxios;
the mock function
export default {
get: jest.fn().mockImplementation(() => Promise.resolve({ data: {} }) )
};
so Im supposed to get a p element with some text but I get nothing. I have tried many different things bt cant seem to get it work not sure why its not working
So I figured it out it turns out you have to call axios.mockresolved value before the rendering of the component, otherwise it will just use the value you provided as the default in your mock axios module.
import React from 'react';
import ReactDOM from 'react-dom';
import TestAxios from '../test_axios.js';
import {act, render, fireEvent, cleanup, waitForElement} from '#testing-library/react';
import axiosMock from "axios";
afterEach(cleanup)
it('Async axios request works', async () => {
axiosMock.get.mockResolvedValue({data: { title: 'some title' } })
const url = 'https://jsonplaceholder.typicode.com/posts/1'
const { getByText, getByTestId, rerender } = render(<TestAxios url={url} />);
expect(getByText(/...Loading/i).textContent).toBe("...Loading")
const resolvedEl = await waitForElement(() => getByTestId("title"));
expect((resolvedEl).textContent).toBe("some title")
expect(axiosMock.get).toHaveBeenCalledTimes(1);
expect(axiosMock.get).toHaveBeenCalledWith(url);
})