How to load third party libraries in isomorphic reactjs apps? - javascript

I am trying to use the stripe library specifically stripe elements so I can set up a custom form for payment processing. I am using the mern-starter in the server.js file I have the following code. You can see that at the bottom I have added a script tag to import stripe. However, in my client folder I have a component that is trying to make use of stripe and it cannot seem to access it. My guess is that is doesn't know it exists yet, but how can I circumvent that issue? I have looked at a react component that specifically deals with loading scripts, but it didn't seem like a great solution. I was just wondering if anyone else out there knows a better way. I know I could use a callback and have that dispatch and action(using REDUX) when it is done loading and only then allow my stripe code to execute, but again this seems pretty annoying to do. Any insights on this issue would be appreciated.
return `
<!doctype html>
<html>
<head>
${head.base.toString()}
${head.title.toString()}
${head.meta.toString()}
${head.link.toString()}
${head.script.toString()}
${process.env.NODE_ENV === 'production' ? `<link rel='stylesheet' href='${assetsManifest['/app.css']}' />` : ''}
<link href='https://fonts.googleapis.com/css?family=Lato:400,300,700' rel='stylesheet' type='text/css'/>
<link rel="shortcut icon" href="http://res.cloudinary.com/hashnode/image/upload/v1455629445/static_imgs/mern/mern-favicon-circle-fill.png" type="image/png" />
</head>
<body>
<div id="root">${html}</div>
<script>
window.__INITIAL_STATE__ = ${JSON.stringify(initialState)};
${process.env.NODE_ENV === 'production' ?
`//<![CDATA[
window.webpackManifest = ${JSON.stringify(chunkManifest)};
//]]>` : ''}
</script>
<script src='${process.env.NODE_ENV === 'production' ? assetsManifest['/vendor.js'] : '/vendor.js'}'></script>
<script src='${process.env.NODE_ENV === 'production' ? assetsManifest['/app.js'] : '/app.js'}'></script>
<script src='https://js.stripe.com/v3/'></script>
</body>
</html>`;

Your issue is that your application scripts are running before stripe.js has been loaded.
put <script src='https://js.stripe.com/v3/'></script> in the head or, at the very least, before your app (app.js in this case).

Related

Why is firebaseConfig not picked up in javascript?

I am following this tutorial to add Firebase auth to an appengine app. It works except I always get the warning as if (typeof firebase === 'undefined') in index.html is always true. I may have put something in the wrong place (noob at web stuff). Here is what I have done (I have removed some comments and the msgbox display code):
<script>
if (typeof firebase === 'undefined') {
const msg = "Please paste the Firebase initialization snippet into index.html. See ...";}
</script>
<script src="https://www.gstatic.com/firebasejs/ui/4.5.0/firebase-ui-auth.js"></script>
<link type="text/css" rel="stylesheet" href="https://www.gstatic.com/firebasejs/ui/4.5.0/firebase-ui-auth.css">
<script src="{{ url_for('static', filename='script.js') }}"></script>
<link type="text/css" rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body>
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/7.8.0/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-analytics.js"></script>
<script>
var firebaseConfig = {
the secrets from firebase which work };
the rest is verbatim from the example
I have tried putting firebaseConfig in the header, same problem.
firebase won't have a value until after you include firebase-app.js. Right now, you are checking it before the inclusion. The order matters a lot. Just move the scripts above the code that uses them.
Also, the versions of your firebase scripts need to match exactly - what you show right now have version conflicts.
<!-- The core Firebase JS SDK is always required and must be listed first -->
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.1/firebase-analytics.js"></script>
<script>
if (typeof firebase === 'undefined') {
const msg = "Please paste the Firebase initialization snippet into index.html. See ...";}
// now you can call firebase.initializeApp()
</script>

Blazor WebAssembly Environment Variables

I'm currently working on a .NET Standard 2.1 Blazor WebAssembly application.
I try to include or exclude Stylesheets according to an environment variable.
In .NET Core there are usually Environment Tag Helpers like in the following example:
<environment include="Development">
<link rel="stylesheet" href="css/style.css" type="text/css" />
</environment>
<environment exclude="Development">
<link rel="stylesheet" href="css/style.min.css" type="text/css" />
</environment>
This works perfectly fine in a Blazor Server application, but doesn't in Blazor WASm, as this is client-side code.
Thus I try to find a good solution to include/exclude Style sheets according to the Environment variable in Blazor WebAssembly.
My current approach is to call a JavaScript helper method from my Blazor WASm Program.cs file with JSInterop and remove the Stylesheets according to the environment variable:
await jsInterop.InvokeVoidAsync("helpers.setup", "Development");
My JavaScript on the client looks like this:
window.helpers = {
setup: (environment) => {
if (environment === "Development") {
// remove production styles
}
if (environment !== "Development") {
// remove development styles
}
}
};
The problem with this solution is, I want to put my styles into my header file and group them into a <section> element or something similar - which doesn't work in valid HTML5.
How do you handle your Development/Production environment in Blazor WebAssembly?
How can you exclude or include specific CSS files according to the set environment variable in the project settings (launchsettings.json)?
Disclaimer:
This is just something I tried that seems to work. I could not find any documentation supporting doing it this way, nor anything saying not to do it this way. if there is any official documentation please let me know.
The documentation state:
When running an app locally, the environment defaults to Development.
When the app is published, the environment defaults to Production.
Further down it does mention how to set the environment via the web.config that gets generated when publishing the file to IIS.
There are also references to Use multiple environments in ASP.NET Core. and Host and deploy ASP.NET Core Blazor WebAssembly
However this is what I did.
Looking at the Program.cs file that was generated by the new web assembly project template, the builder is created by WebAssemblyHostBuilder.CreateDefault(args); This must mean that all the default services must already be registered in the services container.
This would include the IWebAssemblyHostEnvironment configuration service.
The next line down builder.RootComponents.Add<App>("app"); adds the App <app></app> root component that is used in the index.html file.
So, Why not try to create a Head <head></head> component and see what happens.
I created a Head razor component and named it Head.razor containing all the html that would usually live between the <head></head> tags.
#using Microsoft.AspNetCore.Components.WebAssembly.Hosting
#inject IWebAssemblyHostEnvironment hostEnv
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/app.css" rel="stylesheet" />
#*Check the environment value*#
#if (hostEnv.IsDevelopment())
{
<title>BlazorWasmApp - In Debug</title>
<link href="css/debug.css" rel="stylesheet" />
}
else
{
<title>BlazorWasmApp - Not Debug</title>
<link href="css/live.css" rel="stylesheet" />
}
#code {}
Because it is a component you can inject the IWebAssemblyHostEnvironment and check the .IsDevelopment(),.IsProduction() etc.. extension method values.
I left the original <head> tag as is in the index.html file as the content of the <head>...gets overwritten...</head> seems to be completely overwritten.
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>BlazorWasmApp</title>
<base href="/" />
<link href="css/app.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
...
...
Also leaving the <head>tag with the reference to the cs/app.css file does not change the way it looks when the app is Loading....
I registered the Head class to the builder.RootComponents collection in the Program class.
public static async Task Main(string[] args)
{
var builder = WebAssemblyHostBuilder.CreateDefault(args);
builder.RootComponents.Add<App>("app");
//Add the Head to root components
builder.RootComponents.Add<Head>("head");
builder.Services.AddTransient(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
await builder.Build().RunAsync();
}
I added 2 css files to the wwwroot/css folder debug.css and live.css each containing a simple body { background-color:*red or blue* } style.
In the launchSettings.json file, in the profiles section, set the IIS Express : environmentVariables : ASPNETCORE_ENVIRONMENT to "Development" and under the [YourAppName] : environmentVariables : ASPNETCORE_ENVIRONMENT to "Production".
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
},
"BlazorWasmApp": {
"commandName": "Project",
"launchBrowser": true,
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Production"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000",
"inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}"
}
}
When launching the app with the IIS Express profile (Development) the background is red and when launching the app with [YourAppName] profile (Production) the background is blue.
When looking at the <head></head> tags using the developer tools the content of the head tag contains the css references according to the environment.
IIS Express:
BlazorWasmApp (my app profile):

Chardin Js , Hybrid Cordova mobile application - "undefined" is not a function

I am trying to create "coach marks"/ instruction overlays in my hybrid mobile app using Jquery and the Chardin.js library : https://github.com/heelhook/chardin.js
But unfortunately I keep getting this error :
[FATAL] [NONE] Uncaught Exception: TypeError: 'undefined' is not a function (evaluating '$('body').chardinJs('start')') at (compiled_code):5
this is how my JS file looks like :
$(document).ready(function() {
console.log("IN CHARDIN INIT");
$('.container').chardinJs('start');
});
And I load all the files in the HTML file like this (this code is not showing all the div elements for simplicity):
<head>
<link rel="stylesheet"
href="../../css/jquery/mobile/1.3.2/jquery.mobile.structure-1.3.2.min.css" />
<script src="../../js/jquery/mobile/1.3.2/jquery.mobile-1.3.2.min.js"></script>
<!-- Chardin/ Coach marks stuff -->
<script src="../../js/chardin/chardinjs.min.js"></script>
<link href="../../js/chardin/chardinjs.css" rel="stylesheet" />
</head>
<body>
<!-- Coach marks stuff -->
<script type="text/javascript" src="../../js/chardin/chardinInit.js"></script>
</body>
Am I doing something wrong here ??
After days of debugging I found out that the ChardinJs lib was not loading and I had to add it to the body of HTML to load.
The other thing was that Chardin JS has a dependancy that is not mentioned on their website. It needs the bootstrap plugin that I was missing. As soon as I added this dependancy, It started working.

can't include js file in pyramid project

I'm trying to use an external js file to use in my pyramid project.
I found this solution but i can't seem to get it work.
The js files i want to include are in C:\env\uza\uza\static\js
project name = uza.
In my template i use this to call the script:
<script type="text/js" src="${request.static_url('uza:static/js/fabtabulous.js')}" />
<script type="text/js" src="${request.static_url('uza:static/js/tablekit.js')}" />
my init.py looks like this:
config.add_static_view('static', 'static', cache_max_age=3600)
When i navigate to the page in my browser it just gives me the pyramid sidebar in raw html code. I know it's a stupid mistake i made somewhere but i can't seem to find it. Is annyone able to help me with this.
EDIT:
I uploaded a pdf to give a better understanding of the problem i'm having.
ps: there are no errors in console.
https://dl.dropboxusercontent.com/u/6752022/problem.pdf
EDIT:
I made a new project using the sqlalchemy scaffold.
The changes I made are:
- include this line in the mytemplate.pt
<script type="text/js" src="${request.static_url('javascript:static/js/tette.js')}" />
<input type="button" onclick="popup()" value="Click Me!">
- i didn't change annything else because i don't think anny other changes need to be made in the scaffold.
my tette.js file looks like this:
function popup() {
alert("Hello World")
}
This is the output i have before including the js file. (deleted a few divs)
And this is after.
what am I doing wrong ? thanks in advance.
Can you back it out to a point to where the pyramid sidebar looks and works correctly, and isn't raw HTML?
Your init.py line looks correct. Then in your templates you can get at whatever is in the 'static' folder like so:
<link rel="stylesheet" href="${request.static_url('myproject:static/style.css')}">
<!--[if lte IE 6]>
<link rel="stylesheet" href="${request.static_url('myproject:static/ie6.css')}" type="text/css" media="screen"
charset="utf-8"/>
<![endif]-->
<script type="text/javascript"
src="${request.static_url('myproject:static/tinymce/jscripts/tiny_mce/tiny_mce.js')}"></script>
it's as Peter Tirrell says.
I didn't say the type was javascript.

Use of Modernizr.load

I am using Modernizr for conditional loading of resources. My code is
<link rel="stylesheet" type="text/css" media="all" href="stylesheet/style.css" />
<script type="text/javascript" src="javascript/jQuery/jquery-1.8.1.min.js"></script>
<script src="javascript/stickyheader/jquery.fixedheadertable.js"></script>
<link rel="stylesheet" type="text/css" media="all" href="javascript/stickyheader/defaultTheme.css" />
<script type="text/javascript" src="javascript/modernizr/modernizr.2.6.2.js"></script>
<script type="text/javascript">
Modernizr.load([ {
// If browser supports touch
test : Modernizr.touch,
//Load iPad related resorces
yep : [ 'javascript/ipad-default.js', 'javascript/touchscroll.js', 'javascript/ipad-scroll.js',
'javascript/mobile.js' ],
// Load common resorces
load : ['javascript/ipad-default.js']
} ]);
</script>
This is working fine. But I am wondering if I can load all resources in Modernizr.load when I test for Modernizr.touch.
To be clear I want to load all resources within Modernizr.load.
How can I do this? And is this a good approach?
Yes you can. It definitely is a good approach to use a resource loader for a web application. However, I found the page rendering to be a little shattering when loading all CSS through Modernizr.
// You can load CSS just like JS
Modernizr.load("stylesheet/style.css", [
{
test : Modernizr.touch,
yep : [ 'javascript/touchscroll.js', 'javascript/ipad-scroll.js', 'javascript/mobile.js' ],
load : [ 'javascript/ipad-default.js' ] // No need to specify this in 'yep' too
}]);
Because Modernizr.load is built on yepnope.js, the yepnope documentation is a little more interesting for resource loading than the Modernizr tutorials. If you don't mind yet another framework, I can recommend requirejs. This one really helps to decouple and load your components.

Categories