Currently I am using legacy checkout form of stripe ( open in popup ) in angularjs, and now I want to upgrade the stripe to version 3 with redirectToCheckout flow.
How to integrate Stripe v3 in angularjs with custom product? I can't add all my products in the stripe.
My current code is like :
var stripe = Stripe(data.stripeKey);
stripe
.redirectToCheckout({
lineItems: [
// Replace with the ID of your price
// Here i want to add custom product names and price for that product
{price: "123", quantity: 1},
],
mode: 'payment',
successUrl: 'https://your-website.com/success',
cancelUrl: 'https://your-website.com/canceled',
})
.then(function(result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
});
And also, angularjs is a front end of restapi so, everything is managed by the request and response so, how to implement the charge and capture flow in this? ( can this be achieved without webhooks? )
You can't use 'ad-hoc' prices with the client-only redirectToCheckout. Instead you'd need to introduce a server-side component to create a Checkout Session, where you can use the price_data parameter.
Normally in django with templates I implement basic notifications like this.
For example.
class Article(models.Model):
name = models.CharField()
owner = models.ForeignKey(User)
class Comment():
article = models.ForeignKey(Article)
txt = models.CharField()
user = models.ForeginKey()
datetime = models.DateTimeField(auto_now_add=True)
class ArticleNotification():
article = models.ForeignKey(Article)
msg = models.CharField()
is_seen = models.BooleanField(default=False)
datetime = models.DateTimeField(auto_now_add=True)
If someone commented on article the owner will see notifications.
#transaction.atomic
def post_comment(request, article_id):
comment = Comment.objects.create(article_id=article_id, txt="Nice Article", user=request.user)
ArticleNotification.objects.create(article_id=article_id, msg=f"User {request.user} commented on your post")
Now to show the notifications I normally make a context processor:
# context_processor:
def notifcations(request):
notifs = Notfication.objects.filter(article__owner=request.user).order_by("-datetime")
return {"notifs":notifs}
In this way I can normally implement basic notification system with refresh.
Now in (drf + react) what will be the preferred way for this type of task.
Instead of context processor should I have to make an get api to list notifications
And call this api on every request from react frontend ?
Instead of context processor should I have to make an get api to list notifications
Yes. You can create DRF API view like this
serializers.py
class ArticleNotificationSerializer(ModelSerializer):
class Meta:
model = ArticleNotification
fields = ["id", "article", "msg", "is_seen", "datetime"]
views.py
class ArticleNotificationListView(ListAPIView):
serializer_class = ArticleNotificationSerializer
queryset = ArticleNotification.objects.all()
urls.py
path('notification', ArticleNotificationListView.as_view()),
And call this api on every request from react frontend ?
Yes. Also you can check for Notifications for every 10 seconds with setInterval and componentDidMount hook in your react component.
componentDidMount: function() {
this.countdown = setInterval(function() {
axios.get(
'/notifications/'
).then(r =>
this.setState({ notifications: r.data }); // Changing state
)
}, 10000);
},
For real-time notification, you need something like Django channels or you can set a get api from react which runs after every defined time (say 5 minutes) and would fetch the required notifications based on user.
In your case things in context processor would be in listapiview and later you can fetch all the list.
I built a blog with React that fetches the data for each blog entry dynamically from an api.
The page's content obviously looks different depending on the route, e.g. mysite.com/blog/1, mysite.com/blog/2, ...
What I want to achieve is to dynamically change the meta descriptions depending on the data that is fetched from the api based on the url. In particular the og:title, og:description and og:image. Is something like that even possible?
I read about SSR/Next.JS or Gatsby but I am not sure if this is working if the data is received from api calls.
I understand that SSR would render the content on the server, hence it allows Google to crawl the pages but wouldn't that exclude api calls?
I also understand that Gatsby builds static sites but for me that wouldn't work because the api calls are dynamic and cannot be built into a static site.
I would highly appreciate some hints to point me in the right direction.
I understand that SSR would render the content on the server, hence it
allows Google to crawl the pages but wouldn't that exclude api calls?
I also understand that Gatsby builds static sites but for me that
wouldn't work because the api calls are dynamic and cannot be built
into a static site.
I think you've misunderstood how Gatsby works.
To summarize, Gatsby generates static pages from dynamic data (API calls) so, when you run the gatsby develop or gatsby build command, Gatsby fetches the data from the sources (in this case from your API) and generates dynamic pages (mysite.com/blog/1, mysite.com/blog/2, etc).
This data is static, meaning that each change of those sources, will force you to re-fetch the data to display the changes (in production means a new deployment) but, as soon as your pages are built statically, you can build your SEO data on the fly.
This is an old Gatsby's workflow that they used to have on their old website but I find it quite self-explanatory:
In the build-time, your site is being statically generated so, you can fully customize your SEO requirements with a custom SEO component or whatever your want. Most of the starters come with a SEO component ready to be used:
function Seo({ description, lang, meta, title }) {
const { site } = useStaticQuery(
graphql`
query {
site {
siteMetadata {
title
description
author
}
}
}
`
)
const metaDescription = description || site.siteMetadata.description
const defaultTitle = site.siteMetadata?.title
return (
<Helmet
htmlAttributes={{
lang,
}}
title={title}
titleTemplate={defaultTitle ? `%s | ${defaultTitle}` : null}
meta={[
{
name: `description`,
content: metaDescription,
},
{
property: `og:title`,
content: title,
},
{
property: `og:description`,
content: metaDescription,
},
{
property: `og:type`,
content: `website`,
},
{
name: `twitter:card`,
content: `summary`,
},
{
name: `twitter:creator`,
content: site.siteMetadata?.author || ``,
},
{
name: `twitter:title`,
content: title,
},
{
name: `twitter:description`,
content: metaDescription,
},
].concat(meta)}
/>
)
}
Since the component is taking description, lang, meta and title as a props respectively, you can add it in your blog template to take dynamic data that will be built statically, meaning that, when your site will be deployed, that data will be already built, so Google crawlers will get it instantly.
const YourBlogPostTemplate = ({ data }) =>{
return <article>
<SEO title={data.allAPIData.frontmatter.title} />
<h1>I'm the title: {data.allAPIData.frontmatter.title}</h1>
</article>
}
Note: I won't fully customize it to avoid extending the answer, but get the idea.
The SEO component will be taking the title and the rest of the fields in the build-time.
Your API calls are fetched before the page is built so, at the time your page is being built your data is already static.
There is a pretty good article here that describes how to work around this issue the easiest way.
Basically, I needed to put a simple NodeJS server on top of my current React application. The server is now serving the files from the build directory. For some routes, I am simply replacing the __PAGE_META__ placeholder with the meta tags needed for Google, Facebook, Twitter, etc.
Here is a simple picture to describe the flow:
And a simple code snippet of the NodeJS part:
const path = require("path")
const express = require("express")
const app = express()
const fs = require("fs")
//
const pathToIndex = path.join(__dirname, "build/index.html")
app.get("/", (req, res) => {
const raw = fs.readFileSync(pathToIndex)
const pageTitle = "Homepage - Welcome to my page"
const updated = raw.replace("__PAGE_META__", `<title>${pageTitle}</title>`)
res.send(updated)
})
//
app.use(express.static(path.join(__dirname, "build")))
app.get("*", (req, res) =>
res.sendFile(path.join(__dirname, "build/index.html"))
)
const port = process.env.PORT || 5000
app.listen(port, () => {
console.log(`Server started on port ${port}`)
})
For the dynamic site, an api can be called and the page meta can be replaced with the information appropriately.
I have an existing api which I am using to get data to my react application, however, I created a new api which I want to connect to the react app. Wondering what is the solution to get data from 2 separated api on the same time?
I have a base url as it below:
let sessionToken = localStorage.getItem('currentUser.sessionToken')
axios.defaults.baseURL = urls.baseUrl(url),
if (sessionToken) {
axios.defaults.headers.common.Authorization = `Token token=${sessionToken}`
}
}```
I am learning React and want to create an application with Symfony4 as my backend and React frontend. I am stuck now when I need to pass some kind of data to the frontend from my backend. I don't really know what is the right way to do it? Following some tutorials I am doing it like this:
From the controller I send some data to the twig file:
/**
* #Route("/")
*/
public function homepage()
{
$date = new DateTime();
$curr_date = $date->format('Y-m-d H:i:s');
return $this->render('base.html.twig', [
'gameDate' => $curr_date
]);
}
In the twig file, I set it as a data-attribute
base.html.twig:
<div id="root" data-event-date="{{ gameDate }}">
Then I can get the variable as a dataset in my JavaScript
App.js:
const root = document.getElementById('root');
ReactDOM.render(<Homepage {...(root.dataset)}/>, root);
And render it from props.
Homepage.js:
class Homepage extends Component {
constructor(props) {
super(props)
this.state = {
prizePool: '',
gameDate: '',
numberOfPlayers: ''
}
}
onParticipateClick = (event) => {
this.setState({prizePool: Math.random()})
}
render()
{
return (
<div className="mt-c-10">
<GameInfoBox gameDate={this.props.eventDate}/>
</div>
)
}
}
This actually works, but I am concerned with showing all the information in data variables because anyone can see it. What if I want to pass user ID or something secret? There should be another way to do it right?
It depend on what you attemps, if you are working on big project, you can use API to serve backend data. Take a look here: https://www.modernjsforphpdevs.com/react-symfony-4-starter-repo/. There is a simple example.
But if you want something more use api-platform or FOSRestBundle.
"Best and safest" is a little ambiguous - do you need strict security, or safe as in code stability etc?
Instead of passing your data from controller to view (twig) and then into HTML elements or global, another way is this:
Controller loads the view file with your nav and other stuff
Controller loads React (however you do this, Webpack etc)
React calls another controller (i.e. fetch()). This controller is probably somewhere like src/Api/Controller/ as it wont render a view so keep it separate to the other controllers which do render a view
The API controller calls your DB or remote API (etc) and gets the data and sends it back as JsonResponse back to React.
React can then show the data, or an error message depending on the response status
The API controller in your MW can also handle errors and do some logging, so React just gets a 200 and the data or a 400 (or whatever) and it can show a nice message to the user as normal.