Stripe Checkout Button Does Not Display When Using Angular Routes - angularjs

I'm currently trying to implement the standard Stripe Payments checkout dialogue. When I drop in the short <script> include described in the docs (https://stripe.com/docs/checkout) the button that should display is not being rendered.
When I put it in my top-level index.html file the button DOES display. When I put it into a partial that gets displayed when hitting a particular route it does not. I assume this is because it is not executing the Javascript because it's not happening at page load when it's in a route.
Is there anything I can do to get this to work in a route or should I just implement a custom form that points to the stripe.js library? Thanks.

The issue is that the js does not fire, as you suggested. A solution is to simply include the Stripe checkout.js in your index.html file, and then trigger the Stripe popup to open with your controller (or elsewhere).
In your index.html (or equivalent)
<script src="https://checkout.stripe.com/checkout.js"></script>
<!-- Angular script(s) -->
In your controller (or elsewhere)
var handler = StripeCheckout.configure({
key: 'pk_test_6pRNASCoBOKtIshFeQd4XMUh',
image: '/img/documentation/checkout/marketplace.png',
locale: 'auto',
token: function(token) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
}
});
handler.open({
name: 'Stripe.com',
description: '2 widgets',
amount: 2000
});
// handler.close();
This is an adaptation per the Stripe docs at: https://stripe.com/docs/checkout#integration-custom

Related

Embed a dynamic HTML page in reactjs application

I am migrating a JSF app to Node/React js. One of the requirements is to show an html page that is dynamically
requested from a third party in one of the on the page. The third party html is complex - it has its
own javascript and css links to render a canvas. Let me know if this is feasible.
I have
checked in debugger that the requested html arrives successfully.
made sure that it is a valid html by copying it to a file and opening it in different browsers
made sure that all the referred scripts and css are accessible
made sure there are no CORS error
tried wrapping the html in tag
Please see below compressed code. It compiles, rest of the page is rendered but div with third party html
remains blank. If I inspect the div I can see the html but I think none of the javascript code is executed.
class STMDrwaingtDiv extends React.Component
{
constructor(props)
{
//Just create some state variables to track the http request status and
//store the response text
}
getPrevDrawing(caller)
{
//make http request
//caller.setState({cnvHtml:"<object> "+prevDrawing+" </object>"});
//I have tries wrapping the html in <object> tag - does not work
caller.setState({cnvHtml:prevDrawing});
}
componentDidMount()
{
this.getPrevDrawing(this);
}
render()
{
//display progessbar handle errors etc.
else
{
return <div dangerouslySetInnerHTML={{__html:this.state.chartHtml}} />;
}
}
}
https://www.w3schools.com/tags/tag_iframe.asp
Use an <iframe> instead of a <div>. Iframes are meant to be used to embed HTML documents (web pages) inside of other HTML documents! Setting the src attr of the iframe to the 3rd party URL should embed their HTML automatically in your page.

Facebook Pixel Custom Dimensions Only Appearing on First Pageview

We have a single page Angular app with the Facebook pixel that is injected via GTM. In the first injection, we pass the following:
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '<OUR ID>'); // Insert your pixel ID here.
</script>
Note, there is no pageview event. We then push a custom "virtual pageview" event to the GTM datalayer that leads to a tag that sends the pageview to Google Analytics (working fine), and triggers an injection of the following code as well:
<script>
fbq('track', 'PageView', {
dim1:{{dim 1 macro}},
dim2:{{dim 2 macro}},
dim3:{{dim 2 macro}}
});
</script>
On EACH pageview, the above fbq is appended to the DOM with the proper dimensions populated (by viewing the source of the page).
On the FIRST pageview HIT to Facebook, the dimensions are present in the call (by viewing the network tab), but on the SUBSEQUENT pageviews, a hit is sent to Facebook, BUT no dimensions are sent, even though they are present in the code appended to the DOM.
For the most part, these dimensions do not change hit to hit, but could change based on the actions the user does throughout their sessions.
Any thoughts as to why the subsequent hits DO NOT include the custom dimensions?
You try to update a payload every time a history change happens in an Angular app and execute the fb code again with the updated payload?
I would implement a datalayer on your front-end:
<script>
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
event: 'virtualPageView',
pagePath: '/newPath', //update this path from your angular route,
//or use GTMs built in history-change trigger
//and a variable that gets the URL fragment
//to update your pageview's path variable.
customDimenson1: 'value1',
customDimenson2: 'value2',
customDimenson3: 'value3'
});
</script>
Create a trigger of the type Custom Event with the name virtualPageView.
Create 4 variables of the type Data Layer Variable, for pagePath, customDimension1-3.
Create your Custom HTML Tag which contains your fbq event:
<script>
fbq('track', 'PageView', {
dim1:{{customDimenson1}},
dim2:{{customDimenson2}},
dim3:{{customDimenson3}}
});
</script>
Create another Custom HTML Tag that fires on the built-in trigger All Pages, as it only needs to be executed once for your Single Page Application, with your base code:
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', '<OUR ID>'); // Insert your pixel ID here.
</script>
I had problems with SPA for updated variables. Sometimes it's a race condition, sometimes it's bugs in GTM or your code. You can also try to delay the execution by using a 100ms timer (bad advice).
Received feedback from the official Facebook team, it seems that this is by design. On any subsequent call with a Pageview event, no custom data will be sent in the payload.

how i can read meta tag from template before load it on $routeChangeStart in angularjs

i have angular app and server send to me dynamic html when routing to some page and this page have metatag for some use. i have to chenge url if the meta tag is not set before thmplate is load. how i can read meta tag befor load template in $routeChangeStart
So what i can understand via your statement, is you want to get the meta information before loading the next page. Below is snippet, you will need to modify according to your requirement. If you are using Angular UI routing then this should work.
$scope.$on('$routeChangeSuccess', function (event) {
$http.get('url').then(function(response) {
html = response.data; // Check the meta information and then
//either move or stop propagation.
});
});
Hope this helps.

Angular ngView with CKEditor disappearing text

cutting right to the chase here heh
Building an admin backend system with angular for a client. This site and backend are built with Node and Angular. I've got a post editor setup, so that when you click a link to edit a post, locationProvider and ngRoute go to work and swap out the partial with a new controller, and updates the url.
Here at this point, everything shows up perfectly.
It's when I click on Cancel (which is a standard link going back to the post list view) or submit (which works it's magic and then redirects to the same url as cancel) and this works.
It's when I click on the link to edit the same post again. The content that's supposed to be in the CKEditor is blank. However when using Chrome Dev Tools I can see that tw original input field has the content in it correctly, but the iframe has nothing in it at all but the CKEditor Chrome.
As for code,
In my controller it looks like this:
$scope.post = null;
$http.get('/api/post/'+$routeParams.id)
.success(function(data,status,headers){
$scope.post = data;
});
$(function() {
CKEDITOR.replace("content");
});
$scope.submit = function() {
// submission code here
};
Pretty basic here, just want to get the basics out of the way first.
Is the problem with how I'm loading CKEditor?
CKEDITOR.replace("content") would replace the html element with CKEditor instance. Assuming "content" is some div id or text area in your html.
To set the content you need to use
CKEDITOR.instances["content"].setData("Contents to be displayed in text area");

Integrate external script with parameters in angularjs

I am trying to integrate intercom.io in my AngularJS application.
The script has some parameters to configure before the full loading:
<script id="IntercomSettingsScriptTag">
window.intercomSettings = {
// TODO: The current logged in user's email address.
email: "john.doe#example.com",
// TODO: The current logged in user's sign-up date as a Unix timestamp.
created_at: 1234567890,
app_id: "95b20cd5364bab3a2136e252d2862b8136aabe7e"
};
</script>
<!-- Init script -->
<script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://static.intercomcdn.com/intercom.v1.js';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}};})()</script>
I tried to use {{data.email}} to replace the email but unfortunately, the init script get loaded before the intercomSettings. ng-cloak is not very useful for me because it has been designed only for presentation purposes.
I am not sure in which direction I should look for.
To test my code: http://plnkr.co/edit/2PJNLukBx0cTOPZXNwqs?p=preview
You should get a little question mark at the bottom right of the window if it works.
I'm not sure if you already found a solution, but you should take a look on this:
https://github.com/maxiperezc/angular-intercom
it basically wrapped intercom script into angular, so you can use within your application using directives.
This is an improved version of https://github.com/gdi2290/angular-intercom - they removed some unnecessary code
I updated angular-intercom to the latest intercom api if you're still interested. The service has been simplified for the user with a better way of handling async script loading
https://github.com/gdi2290/angular-intercom

Resources