ADSK Forge Viewer displays my 3D DWG as only 2D - node.js

I am create a web app and using the Forge viewer to display my models, but when I upload and translate a 3D DWG model to svf for viewing I am only seeing 2D. It is a 3D DWG model, but the viewer is only displaying it as a 2D model instead. Is there something I'm missing within the viewer.html code? I can't seem to find where the mistake is.
viewer.html (Used from a sample project on github)
<!DOCTYPE html>
<html>
<head>
<title>Autodesk Forge: 3D Viewer App Sample</title>
<meta http-equiv="cache-control" content="max-age=0" />
<meta http-equiv="cache-control" content="no-cache" />
<meta http-equiv="expires" content="0" />
<meta http-equiv="expires" content="Tue, 01 Jan 1980 1:00:00 GMT" />
<meta http-equiv="pragma" content="no-cache" />
<!-- Third Party package -->
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<!-- Autodesk Forge Viewer files (IMPORTANT) -->
<link rel="stylesheet" href="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/style.min.css"
type="text/css" />
<script src="https://developer.api.autodesk.com/modelderivative/v2/viewers/7.*/viewer3D.min.js"></script>
<style>
/** Just simple CSS styling to make this page a little nicer **/
body {
margin: 0;
padding: 0;
}
</style>
</head>
<body>
<!-- The Viewer will be instantiated here -->
<div id="MyViewerDiv"></div>
<!-- Custom script -->
<script>
var viewer;
var options = {
env: "AutodeskProduction",
api: "derivativeV2", // TODO: for models uploaded to EMEA change this option to 'derivativeV2_EU'
getAccessToken: getForgeToken
};
var documentId = "urn:" + getUrlParameter("urn");
console.log(documentId);
// Run this when the page is loaded
Autodesk.Viewing.Initializer(options, function onInitialized() {
// Find the element where the 3d viewer will live.
var htmlElement = document.getElementById("MyViewerDiv");
if (htmlElement) {
// Create and start the viewer in that element
viewer = new Autodesk.Viewing.GuiViewer3D(htmlElement);
viewer.start();
// Load the document into the viewer.
Autodesk.Viewing.Document.load(
documentId,
onDocumentLoadSuccess,
onDocumentLoadFailure
);
}
});
/**
* Autodesk.Viewing.Document.load() success callback.
* Proceeds with model initialization.
*/
function onDocumentLoadSuccess(doc) {
// Load the default viewable geometry into the viewer.
// Using the doc, we have access to the root BubbleNode,
// which references the root node of a graph that wraps each object from the Manifest JSON.
var viewable = doc.getRoot().getDefaultGeometry();
if (viewable) {
viewer
.loadDocumentNode(doc, viewable)
.then(function (result) {
console.log("Viewable Loaded!");
})
.catch(function (err) {
console.log("Viewable failed to load.");
console.log(err);
});
}
}
/**
* Autodesk.Viewing.Document.load() failure callback.
*/
function onDocumentLoadFailure(viewerErrorCode) {
console.error(
"onDocumentLoadFailure() - errorCode: " + viewerErrorCode
);
jQuery("#MyViewerDiv").html(
"<p>Translation in progress... Please try refreshing the page.</p>"
);
}
// Get Query string from URL,
// we will use this to get the value of 'urn' from URL
function getUrlParameter(name) {
console.log("Made it here 2");
console.log(name);
name = name.replace(/[[]/, "\\[").replace(/[\]]/, "\\]");
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)");
var results = regex.exec(location.search);
return results === null
? ""
: decodeURIComponent(results[1].replace(/\+/g, " "));
}
// Get public access token for read only,
// using ajax to access route /api/forge/oauth/public in the background
function getForgeToken(callback) {
console.log("Made it here");
jQuery.ajax({
url: "/api/forge/oauth2/public",
success: function (res) {
callback(res.access_token, res.expires_in);
}
});
}
</script>
</body>
</html>
Node JS Code to translate and send to viewer
const express = require("express");
const Axios = require("axios");
const bodyParser = require("body-parser");
const cors = require("cors");
let config = require("./config");
let mainFunc = require("./BP-s3oss");
//Express Server
let app = express();
// let router = express.Router();
app.use(cors());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(__dirname + "/www"));
app.get("/api/s3Data/:bucket", async (req, res) => {
let bucket = req.params.bucket;
let object = decodeURIComponent(req.query.object);
//Log to console
console.log(config.forge.forge_bucket + " " + object);
//Comment KWard: Add in Error check if unsuccessful
try {
//Main Function
let main = await mainFunc(bucket, object);
//Initialize Process
res.redirect("/api/forge/s3toOSS/" + config.forge.forge_bucket + "/" + encodeURIComponent(object));
} catch (error) {
res.status(500).send('Something bad Happened!');
}
});
//Start Express Server on Port 3000
app.set("port", 3000);
var server = app.listen(app.get("port"), function () {
console.log("Server listening on port " + server.address().port);
});
//-------------------------------------------------------------------
// Configuration for your Forge account
// Initialize the 2-legged OAuth2 client, and
// set specific scopes
//-------------------------------------------------------------------
var FORGE_CLIENT_ID = config.forgecredentials.client_id;
var FORGE_CLIENT_SECRET = config.forgecredentials.client_secret;
var access_token = "";
var scopes = "data:read data:write data:create bucket:create bucket:read";
const querystring = require("querystring");
//Route /AWStoFORGE/OSS
app.get("/api/forge/s3toOSS/:bucket/:object", async (req, res) => {
let bucket = req.params.bucket;
let object = req.params.object;
console.log(bucket + " " + object);
res.redirect("/api/forge/oauth" + "/" + encodeURIComponent(object));
});
// Route /api/forge/oauth
app.get("/api/forge/oauth/:object", function (req, res) {
let objectKey = req.params.object;
Axios({
method: "POST",
url: "https://developer.api.autodesk.com/authentication/v1/authenticate",
headers: {
"content-type": "application/x-www-form-urlencoded"
},
data: querystring.stringify({
client_id: FORGE_CLIENT_ID,
client_secret: FORGE_CLIENT_SECRET,
grant_type: "client_credentials",
scope: scopes
})
})
.then(function (response) {
// Success
access_token = response.data.access_token;
console.log("Successful Authentication");
res.redirect(
"/api/forge/datamanagement/bucket/getobject" + "/" + encodeURIComponent(objectKey)
);
})
.catch(function (error) {
// Failed
console.log(error);
res.send("Failed to authenticate");
});
});
// Route /api/forge/oauth2/public
app.get("/api/forge/oauth2/public", function (req, res) {
// Limit public token to Viewer read only
Axios({
method: "POST",
url: "https://developer.api.autodesk.com/authentication/v1/authenticate",
headers: {
"content-type": "application/x-www-form-urlencoded"
},
data: querystring.stringify({
client_id: FORGE_CLIENT_ID,
client_secret: FORGE_CLIENT_SECRET,
grant_type: "client_credentials",
scope: "viewables:read"
})
})
.then(function (response) {
// Successs
res.json({
access_token: response.data.access_token,
expires_in: response.data.expires_in
});
})
.catch(function (error) {
// Failed
console.log(error);
res.status(500).json(error);
});
});
const bucketKey = config.forge.forge_bucket;
const policyKey = "persistent"; // Never Expires
// For converting the source into a Base64-Encoded string
var Buffer = require("buffer").Buffer;
String.prototype.toBase64 = function () {
// Buffer is part of Node.js to enable interaction with octet streams in TCP streams,
// file system operations, and other contexts.
return new Buffer(this).toString("base64");
};
app.get("/api/forge/datamanagement/bucket/getobject/:objectKey", function (
req,
res
) {
let objectVal = req.params.objectKey;
console.log(bucketKey);
console.log(objectVal);
Axios({
method: "GET",
url:
"https://developer.api.autodesk.com/oss/v2/buckets/" +
encodeURIComponent(bucketKey) +
"/objects/" +
encodeURIComponent(objectVal) +
"/details",
maxContentLength: 104857780,
headers: {
Authorization: "Bearer " + access_token,
"content-type": "application/json"
}
})
.then(function (response) {
//Success
console.log("Object Retrieved from Forge OSS");
var urn = response.data.objectId.toBase64();
res.redirect("/api/forge/modelderivative/" + encodeURIComponent(urn));
})
.catch(function (error) {
//Failed
console.log(error);
res.send("Failed to get objectId from OSS.");
});
});
// Route /api/forge/modelderivative
app.get("/api/forge/modelderivative/:urn", function (req, res) {
var decodeURN = decodeURIComponent(req.params.urn)
var urn = decodeURN;
var format_type = "svf";
var format_views = ["2d", "3d"];
// console.log(urn);
Axios({
method: "POST",
url: "https://developer.api.autodesk.com/modelderivative/v2/designdata/job",
headers: {
"content-type": "application/json",
Authorization: "Bearer " + access_token
},
data: JSON.stringify({
input: {
urn: urn
},
output: {
formats: [
{
type: format_type,
views: format_views
}
]
}
})
})
.then(function (response) {
// Success
console.log("Redirected to Viewer HTML");
res.redirect("/viewer.html?urn=" + urn);
// res.send(urn);
})
.catch(function (error) {
// Failed
console.log(error);
res.send("Error at Model Derivative job.");
});
});

Check if the default view of your model is the 2D one that you are seeing as you are loading the default view with:
var viewable = doc.getRoot().getDefaultGeometry();
You can either load a specific view through the DocumentBrowser extension:
const viewer = new Autodesk.Viewing.GuiViewer3D(document.body.children[0],{extensions:['Autodesk.DocumentBrowser']})
Autodesk.Viewing.Document.load('urn:urn', doc=> {
viewer.start()
viewer.loadDocumentNode(doc,doc.getRoot().getDefaultGeometry())
//…
Or specify query to look up a viewable (such as a 3D one) in the document and load it:
Autodesk.Viewing.Document.load('urn:urn', doc=> {
const viewable = doc.getRoot().search({'role':'3d'})[0] //name of viewable for instance
viewer.start()
viewer.loadDocumentNode(doc,viewable)
//...

Adding a little more info to this...
If you want to retrieve the list of views in the document browser extension, here are two ways...
Using DOC object
let myViews = viewer.model.getDocumentNode().search({'role':'3d', type:'view'});
// returns, 5 views in an array
// change the camera view to view #2
viewer.setView(myViews[1]);
// print out the name of the view
console.log( myViews[1].name() );
> "3D_RF_AC1"
Using Extension
let ext = viewer.getExtension("Autodesk.DocumentBrowser");
let myViews = ext.geometries[0].children.filter( i => {
return(i.data.camera)
})
// change the camera view to view #2
viewer.setView( myViews[1] );
// print out the name of the view
console.log( myViews[1].name() );
> "3D_RF_AC1"

Related

Why does fs.readFile return null for first fetch call?

I have a simple function to return a pdf file on my server which works as expected but not the first time the page loads. The first time I try to download the file, the server console log shows me it's there, but the React page console has null. If I click on the download link again, the file contents are returned. Can someone help me please?
React function that calls getDocByLoc (which is itself called by a button click)
async function fetchInvoice(fileLocation) {
setInvoiceStatus('loading');
setInvoice(await invoiceService.getDocByLoc({ location: fileLocation }));
setInvoiceStatus('succeeded');
downloadFile(invoice);
}
// download file
function downloadFile(invoice) {
if (invoiceStatus === 'succeeded') {
let url = window.URL.createObjectURL(invoice);
let a = document.createElement('a');
a.href = url;
a.download = 'test.pdf';
a.click();
}
}
React fetch code
function getDocByLoc(location) {
return fetchWrapper.getDocument(`/invoices/document`, location);
}
fetchWrapper code
function getDocument(url, location) {
const requestOptions = {
method: 'POST',
headers: {
Accept: 'application/json, application/x-www-form-urlencoded',
'Content-Type': 'application/json',
...authHeader(url),
},
credentials: 'include',
body: JSON.stringify(location),
};
return fetch(`${AppSettings.serverEndpoint}${url}`, requestOptions).then(
handleResponseForDocuments
);
}
Node file reader code
function getDocumentByLocation(req, res, next) {
const { location } = req.body;
fs.readFile(location, (err, data) => {
if (err) res.status(500).send(err);
console.log('data: ', data);
res
.contentType('application/pdf')
.send(
`data:application/pdf;base64,${new Buffer.from(data).toString(
'base64'
)}`
);
});
}

Transaction not reflecting on the Paypal App Account

I am successfully making a Platform Transaction on my Platform. All transfers go as expected apart from the Platform Fees. They reflect on the Merchant Seller's side, as well as the Buyer's, but not on the Platform Account.
Transaction details snapshot
The Partner Commission of -$9.33 USD does not show on the Platform account. In fact this transaction does not reflect in any way. There is no way of telling that it ever happened at all from the Paypal Sandbox App Account.
What could it be that I am missing?
Thank you all in advance.
CLIENT SIDE : index.html
<html>
<head>
<meta charset="utf-8"/>
<!-- Optimal rendering on mobile devices. -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Optimal Internet Explorer compatibility -->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- Sample CSS styles for demo purposes. You can override these styles to match your web page's branding. -->
<link rel="stylesheet" type="text/css" href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/css/cardfields.css"/>
<!-- JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?components=buttons,hosted-fields&client-id=Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs" data-client-token="eyJicmFpbnRyZWUiOnsiYXV0aG9yaXphdGlvbkZpbmdlcnByaW50IjoiZWNkYWE1MzZjNjQ5Nzg1YjU2ZWQ5NGMyZGU2ZjRjMGQzY2FiMDY0MzkyNTA3YTkxZTU2MjI3MDlhZTMzOWUyNHxtZXJjaGFudF9pZD1yd3dua3FnMnhnNTZobTJuJnB1YmxpY19rZXk9NjNrdm4zN3Z0MjlxYjRkZiZjcmVhdGVkX2F0PTIwMjEtMDMtMjlUMTM6Mjg6MTMuOTQxWiIsInZlcnNpb24iOiIzLXBheXBhbCJ9LCJwYXlwYWwiOnsiaWRUb2tlbiI6ImV5SnJhV1FpT2lJNVpqWmxOalV5T0RGallXWmhORFU1WkRReU9EWmhPRE5pWVdZMVl6aGtPRFUwWVdNNE5XRmtJaXdpZEhsd0lqb2lTbGRVSWl3aVlXeG5Jam9pVWxNeU5UWWlmUS5leUpwYzNNaU9pSm9kSFJ3Y3pvdkwyRndhUzV6WVc1a1ltOTRMbkJoZVhCaGJDNWpiMjBpTENKemRXSWlPaUpvZEhSd2N6b3ZMM2QzZHk1d1lYbHdZV3d1WTI5dEwzZGxZbUZ3Y0hNdllYVjBhQzlwWkdWdWRHbDBlUzkxYzJWeUwwSlhRazEyZVhoclJsWjBkWHBCZUd4RmNGZENiMVJRTkhSNGFHOVRVMnh0YVZWWmNtbDZhM3BrWkdjaUxDSmhZM0lpT2xzaVkyeHBaVzUwSWwwc0ltRjFaQ0k2SWtGbE5GaFhRM3BIUkZreU5ISkxjR0Y2WkVOdVVtNVVNWGRWYW01Ulh6SlFla3hHTldGUGFIWnBZVlZtVVRkZlR6TTBjbkk0VG5GeWRXNVlaVGRRZUVOcExYTkZkRGR1YjFwbWNqRnZhbUp6SWl3aVlYVjBhRjkwYVcxbElqb3hOakUzTURJME5EazBMQ0poYlhJaU9sdGRMQ0poZWlJNkluTmlMbk5zWXlJc0ltVjRjQ0k2TVRZeE56QXlOVE01TkN3aWMyVnpjMmx2Ymw5cGJtUmxlQ0k2SWxoMVNuUnBiMDU0WWs1YU1HOVFUVzVpTWtkNVpXdHRRMWh3UXlJc0ltbGhkQ0k2TVRZeE56QXlORFE1TkN3aWFuUnBJam9pVlRKQlFVbGtiVVZETTJjekxVTkpOelpDYWtSdk56WjNUVFpoZDJ4VWJuWmFNMGhsVW5kWmNXRmxTazUyZW1SWFpWTmlhMUUyVERoUU5qbFdUako0Y21kR1prTkNUVGxHYVdGRGNVNHhSUzFqTVZobVEzSndZWFJPTWxGWVltczFZbE4yVlZveVpYTlRTRzU1VG1aaWRWUkxZamxQUjB0cWNGRjZSbWR5V0ZFaUxDSmpiR2xsYm5SZmFXUWlPaUpCWlRSWVYwTjZSMFJaTWpSeVMzQmhlbVJEYmxKdVZERjNWV3B1VVY4eVVIcE1SalZoVDJoMmFXRlZabEUzWDA4ek5ISnlPRTV4Y25WdVdHVTNVSGhEYVMxelJYUTNibTlhWm5JeGIycGljeUo5LkhObzlndU5SQVktSDZTR2tUR0xxRUFtbDNWRkJwNHRwNjdSSVJPN1NMbm5PRUtkWGFHSjhfYkJfR3N5dWxZeGQ4Slhnd3duTWV4ejZYaElEUnVtVzVkaDloQm9CbFctTGtNUEZ6cmVDZnk3SnVnbmZPYk9PaWRhV19Wd1IyRXpLSTZ1UzZWaFhKbEFvaWI1U3dfYjNXYlVHR2tudUM5cjZDZ0xlWnNTaDVQZDRuaFc1M0pplatformlHQTZkOVc3ZU5VZXBKNUJwd1FJWkRVYmJyY2JXelFDMzRFN0tQbndjOENIQWh3UGNSZWpWaktWWVlLSE9lUF9KeWpEbFZDWXM4NU5YVEExYV9ldDdFUHZmcmN1NzF0S3FhR0hNV21XWE9KS245UGZ2Zk10b2ZfRWN3SmhVd2RBU1ZqZmU4VjlzM3ZidzRJRGZHMFRjYzY1d2hIaFp4Sl94dyIsImFjY2Vzc1Rva2VuIjoiQTIxQUFJNTNiLVl0Qk1neFlmb1NQZHJKUUsxZTBCYVZSZm01X3BPNlg4bnktZ292S1l3dy11YU1fWm8wM0YxQXdzenZfYjF4RmZJTkE1YkNfUEZya3A0bkxxMzljdWdndyJ9fQ=="></script>
<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs&currency=USD" data-namespace="paypal_sdk"></script>
</head>
<body>
<!-- JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?components=hosted-fields&client-id=Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs&merchant-id=H82BJAGD75E6C&currency=USD&intent=capture" data-partner-attribution-id="FLAVORsb-z1ivv5077605_MP" data-client-token="eyJicmFpbnRyZWUiOnsiYXV0aG9yaXphdGlvbkZpbmdlcnByaW50IjoiZWNkYWE1MzZjNjQ5Nzg1YjU2ZWQ5NGMyZGU2ZjRjMGQzY2FiMDY0MzkyNTA3YTkxZTU2MjI3MDlhZTMzOWUyNHxtZXJjaGFudF9pZD1yd3dua3FnMnhnNTZobTJuJnB1YmxpY19rZXk9NjNrdm4zN3Z0MjlxYjRkZiZjcmVhdGVkX2F0PTIwMjEtMDMtMjlUMTM6Mjg6MTMuOTQxWiIsInZlcnNpb24iOiIzLXBheXBhbCJ9LCJwYXlwYWwiOnsiaWRUb2tlbiI6ImV5SnJhV1FpT2lJNVpqWmxOalV5T0RGallXWmhORFU1WkRReU9EWmhPRE5pWVdZMVl6aGtPRFUwWVdNNE5XRmtJaXdpZEhsd0lqb2lTbGRVSWl3aVlXeG5Jam9pVWxNeU5UWWlmUS5leUpwYzNNaU9pSm9kSFJ3Y3pvdkwyRndhUzV6WVc1a1ltOTRMbkJoZVhCaGJDNWpiMjBpTENKemRXSWlPaUpvZEhSd2N6b3ZMM2QzZHk1d1lYbHdZV3d1WTI5dEwzZGxZbUZ3Y0hNdllYVjBhQzlwWkdWdWRHbDBlUzkxYzJWeUwwSlhRazEyZVhoclJsWjBkWHBCZUd4RmNGZENiMVJRTkhSNGFHOVRVMnh0YVZWWmNtbDZhM3BrWkdjaUxDSmhZM0lpT2xzaVkyeHBaVzUwSWwwc0ltRjFaQ0k2SWtGbE5GaFhRM3BIUkZreU5ISkxjR0Y2WkVOdVVtNVVNWGRWYW01Ulh6SlFla3hHTldGUGFIWnBZVlZtVVRkZlR6TTBjbkk0VG5GeWRXNVlaVGRRZUVOcExYTkZkRGR1YjFwbWNqRnZhbUp6SWl3aVlYVjBhRjkwYVcxbElqb3hOakUzTURJME5EazBMQ0poYlhJaU9sdGRMQ0poZWlJNkluTmlMbk5zWXlJc0ltVjRjQ0k2TVRZeE56QXlOVE01TkN3aWMyVnpjMmx2Ymw5cGJtUmxlQ0k2SWxoMVNuUnBiMDU0WWs1YU1HOVFUVzVpTWtkNVpXdHRRMWh3UXlJc0ltbGhkQ0k2TVRZeE56QXlORFE1TkN3aWFuUnBJam9pVlRKQlFVbGtiVVZETTJjekxVTkpOelpDYWtSdk56WjNUVFpoZDJ4VWJuWmFNMGhsVW5kWmNXRmxTazUyZW1SWFpWTmlhMUUyVERoUU5qbFdUako0Y21kR1prTkNUVGxHYVdGRGNVNHhSUzFqTVZobVEzSndZWFJPTWxGWVltczFZbE4yVlZveVpYTlRTRzU1VG1aaWRWUkxZamxQUjB0cWNGRjZSbWR5V0ZFaUxDSmpiR2xsYm5SZmFXUWlPaUpCWlRSWVYwTjZSMFJaTWpSeVMzQmhlbVJEYmxKdVZERjNWV3B1VVY4eVVIcE1SalZoVDJoMmFXRlZabEUzWDA4ek5ISnlPRTV4Y25WdVdHVTNVSGhEYVMxelJYUTNibTlhWm5JeGIycGljeUo5LkhObzlndU5SQVktSDZTR2tUR0xxRUFtbDNWRkJwNHRwNjdSSVJPN1NMbm5PRUtkWGFHSjhfYkJfR3N5dWxZeGQ4Slhnd3duTWV4ejZYaElEUnVtVzVkaDloQm9CbFctTGtNUEZ6cmVDZnk3SnVnbmZPYk9PaWRhV19Wd1IyRXpLSTZ1UzZWaFhKbEFvaWI1U3dfYjNXYlVHR2tudUM5cjZDZ0xlWnNTaDVQZDRuaFc1M0pplatformlHQTZkOVc3ZU5VZXBKNUJwd1FJWkRVYmJyY2JXelFDMzRFN0tQbndjOENIQWh3UGNSZWpWaktWWVlLSE9lUF9KeWpEbFZDWXM4NU5YVEExYV9ldDdFUHZmcmN1NzF0S3FhR0hNV21XWE9KS245UGZ2Zk10b2ZfRWN3SmhVd2RBU1ZqZmU4VjlzM3ZidzRJRGZHMFRjYzY1d2hIaFp4Sl94dyIsImFjY2Vzc1Rva2VuIjoiQTIxQUFJNTNiLVl0Qk1neFlmb1NQZHJKUUsxZTBCYVZSZm01X3BPNlg4bnktZ292S1l3dy11YU1fWm8wM0YxQXdzenZfYjF4RmZJTkE1YkNfUEZya3A0bkxxMzljdWdndyJ9fQ=="></script>
<!-- Buttons container -->
<div id="paypal-button-container"></div>
<!-- Implementation -->
<script>
let orderId;
// Displays PayPal buttons
paypal_sdk.Buttons({
style: {
layout: 'horizontal'
},
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('/demo/checkout/api/paypal/platform_store_order/create/', {
method: 'post'
}).catch(error => {
console.error('ERR -> fetch : ' + error.message);
}).then(function(res) {
return res.json();
}).catch(error => {
console.error('ERR -> res : ' + error.message);
}).then(function(orderData) {
return orderData.id;
}).catch(error => {
console.error('ERR -> orderData : ' + error.message);
});
},
// Call your server to finalize the transaction
onApprove: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order_platform_store/', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({'orderID': data.orderID, 'payerID': data.payerID})
}).then(function(res) {
return res.json();
}).then(function(orderData) {
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) {
msg += '\n\n' + errorDetail.description;
}
if (orderData.debug_id){
msg += ' (' + orderData.debug_id + ')'
};
return alert(msg); // Show a failure message
}
// Show a success message
alert('Transaction : ' + JSON.stringify(orderData));
});
}
}).render("#paypal-button-container");
</script>
</body>
</html>
NODE app.js
const path = require("path");
var express = require("express");
var cors = require("cors");
var app = express();
var request = require("request");
const port = process.env.PORT || 3000;
app.use(cors());
var bodyParser = require("body-parser");
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.use(bodyParser.json());
// Add your credentials:
// Add your client ID and secret
var CLIENT = "Ae4XWCzGDY24rKpazdCnRnT1wUjnQ_2PzLF5aOhviaUfQ7_O34rr8NqrunXe7PxCi-sEt7noZfr1ojbs";
var SECRET = "EMmNF1LZSOooLUAxEt5csF-rMyIseuV5D6qOoKMzbyUEDaQEhO_DjLarbVsF_vLiXnGHi8qFL13gebg_";
var PAYPAL_API = "https://api-m.sandbox.paypal.com";
const paypal = require("#paypal/checkout-server-sdk");
let environment = new paypal.core.SandboxEnvironment(CLIENT, SECRET);
let client = new paypal.core.PayPalHttpClient(environment);
app.get("/", function (req, res) {
res.sendFile(path.join(__dirname + "/index.html"));
});
// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
app.post("/demo/checkout/api/paypal/order/create/", async function (req, res) {
let ordersCreateRequest = new paypal.orders.OrdersCreateRequest();
ordersCreateRequest.requestBody({
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": "9.88",
},
},
],
});
// Call API with your client and get a response for your call
let createOrder = async function () {
let response = await client.execute(ordersCreateRequest);
return response;
};
let platformOrder = await createOrder();
let orderId = platformOrder.result.id;
// 2. Call /v2/checkout/orders to set up the Order
res.json({
id: orderId,
});
});
// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
app.post("/demo/checkout/api/paypal/platform_store_order/create/", async function (req, res) {
let ordersCreateRequest = new paypal.orders.OrdersCreateRequest();
ordersCreateRequest.requestBody({
"intent": "CAPTURE",
"purchase_units": [
{
"amount": {
"currency_code": "USD",
"value": "31.13",
},
"payee": {
"email_address": "platform#business.example.com",
},
"payment_instruction": {
"disbursement_mode": "INSTANT",
"platform_fees": [
{
"amount": {
"currency_code": "USD",
"value": "9.33",
},
},
],
},
},
],
});
// Call API with your client and get a response for your call
let createOrder = async function () {
let response = await client.execute(ordersCreateRequest);
return response;
};
let platformOrder = await createOrder();
let orderId = platformOrder.result.id;
res.json({
id: orderId,
});
});
// 1. Set up a URL to handle requests from the PayPal button.
app.post("/demo/checkout/api/paypal/order_platform_store/", async function (req, res) {
// 2. Get the payment ID and the payer ID from the request query.
var orderID = req.body.orderID;
request.post(
PAYPAL_API + "/v2/checkout/orders/" + orderID + "/capture",
{
headers: {
"Content-Type": "application/json",
"Authorization": "Bearer A21AAJ8sH_Uq73w8XonQYB9rc1STsZpoK_Q14PkHbRgxtbYUN6FvCg-FbOKYIDlt0Zzo8xVQMvSuCAaRgjSfGoEPYRbxk62xQ",
"PayPal-Partner-Attribution-Id": "FLAVORsb-z1ivv5077605_MP",
},
},
function (err, response, body) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
res.json(response);
}
);
});
app.listen(port, () => console.log(`Listening on port ${port}!`));
Are you a PayPal partner? It's required to use this in the live environment: https://developer.paypal.com/docs/platforms/test-go-live/#2-go-live
If you are, PayPal will guide you in testing this in both sandbox and live modes.
If you are not, you can't use this anyway.

How to make Make and Pay for an Order on Paypal

I am trying to make an order and payment on a Node.js Environment to a user user#email.example.com but no funds get transferred. No errors are thrown.
What could it be that I am missing?
Thank you all in advance.
THE CLIENT SIDE
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Add meta tags for mobile and IE -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<title> PayPal Smart Payment Buttons Integration | Server Demo </title>
</head>
<body>
<!-- Set up a container element for the button -->
<div id="paypal-button-container"></div>
<!-- Include the PayPal JavaScript SDK -->
<script src="https://www.paypal.com/sdk/js?client-id=abc-50mQSYBJpg_OWguVkwn0qCDB-ZAFupw-kq6-k_O1havNEFGH&currency=USD"></script>
<script>
// Render the PayPal button into #paypal-button-container
paypal.Buttons({
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order/create/', {
method: 'post'
}).catch(error => {
console.error('ERR -> fetch : ' + error.message);
}).then(function(res) {
return res.json();
}).catch(error => {
console.error('ERR -> res : ' + error.message);
}).then(function(orderData) {
return orderData.id;
}).catch(error => {
console.error('ERR -> orderData : ' + error.message);
});
},
// Call your server to finalize the transaction
onApprove: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order?orderID=' + data.orderID, {
method: 'get'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) msg += '\n\n' + errorDetail.description;
if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
return alert(msg); // Show a failure message
}
// Show a success message
alert('Transaction completed by ' + JSON.stringify(orderData));
});
}
}).render('#paypal-button-container');
</script>
</body>
</html>
THE NODE SERVER
const path = require("path");
var express = require("express");
var cors = require("cors");
var app = express();
var request = require("request");
const port = process.env.PORT || 3000;
app.use(cors());
var bodyParser = require("body-parser");
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.use(bodyParser.json());
app.get("/", function (req, res) {
res.sendFile(path.join(__dirname + "/index.html"));
});
// Add your credentials:
// Add your client ID and secret
var CLIENT = "abc-50mQSYBJpg_OWguVkwn0qCDB-ZAFupw-kq6-k_O1havNEFGH";
var SECRET = "1234upB-ns0xj5678bpJrkvnkMG4ZUZEHd-0GbPrTe991045673Th1RrqYBqIjhl9Tdm";
var PAYPAL_API = "https://api-m.sandbox.paypal.com";
// Set up the payment:
// 1. Set up a URL to handle requests from the PayPal button
app.post("/demo/checkout/api/paypal/order/create/", function (req, res) {
// 2. Call /v2/checkout/orders to set up the Order
request.post(
PAYPAL_API + "/v2/checkout/orders",
{
auth: {
user: CLIENT,
pass: SECRET,
},
body: {
intent: "CAPTURE",
payer: {
payment_method: "paypal",
},
purchase_units: [
{
amount: {
currency_code: "USD",
value: "10.00",
},
payee: {
email_address: "user#email.example.com",
},
},
],
redirect_urls: {
return_url: "https://mighty-oasis-92039.herokuapp.com/",
cancel_url: "https://mighty-oasis-92039.herokuapp.com/",
},
},
json: true,
},
function (err, response) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
// 3. Return the payment ID to the client
res.json({
id: response.body.id,
});
}
);
});
/** START EXECUTE PAYMENT */
// 1. Set up a URL to handle requests from the PayPal button.
app.get("/demo/checkout/api/paypal/order/", function (req, res) {
// 2. Get the payment ID and the payer ID from the request query.
var orderID = req.query.orderID;
// 3. Call /v2/checkout/orders/{id}/capture to Capture payment for order.
request.post(
PAYPAL_API + "/v2/checkout/orders/" + orderID + "/capture",
{
auth: {
user: CLIENT,
pass: SECRET,
},
json: true,
},
function (err, response) {
if (err) {
console.error(err);
return res.sendStatus(500);
}
// 4. Return a success response to the client
res.json({
status: "success",
});
}
);
});
/** END EXECUTE PAYMENT */
app.listen(port, () => console.log(`url-shortener listening on port ${port}!`));

Uploading blob/file in react-native, contents is empty

I am able to succesfully upload a blob with proper contents from my web browser, but when I do it from react-native, the upload file is empty. Here is the code:
async function doit() {
const data = new FormData();
data.append('str', 'strvalue');
data.append(
'f',
new File(['foo'], 'foo.txt', {type: 'text/plain'}),
);
await fetch('http://localhost:3002/upload', {
method: 'POST',
body: data
});
}
However doing this same code from react-native, it uploads, but the file is empty.
Here is the node.js server I am using to test this. Loading http://localhost:3002 gives you a button called "upload it". Clicking it does the upload from the web. Screenshots of results are below.
var multiparty = require('multiparty');
var http = require('http');
http
.createServer(function (req, res) {
if (req.url === '/upload' && req.method === 'POST') {
console.log('multipart here');
var form = new multiparty.Form();
form.parse(req, function (err, fields, files) {
console.log(require('util').inspect({ fields, files }, false, null, true));
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({ bar: true }));
});
return;
}
console.log('here');
// show a file upload form
res.writeHead(200, { 'content-type': 'text/html' });
res.end(
`
<script>
async function doit() {
const data = new FormData();
data.append('str', 'strvalue');
data.append(
'f',
// new File([new Blob(['asdf'], {type : 'text/plain'})], 'filename.txt'),
new File(['foo', 'what', 'the', 'hell'], 'foo.txt', {type: 'text/plain'}),
);
const res = await fetch('http://localhost:3002/upload', {
method: 'POST',
body: data
});
console.log(JSON.stringify(res, null, 4));
}
document.addEventListener('DOMContentLoaded', () => {
document.getElementById('b').addEventListener('click', doit, false)
}, false);
</script>
<button type="button" id="b">upload it</button>
`
);
})
.listen(3002);
From web browser we see the node server logs this, notice file size is 14.
However from react-native we see file size is 0:
I faced the same problem recently while posting an image from a react-native app to a server. However, I was able to make it work by appending the name and type of the file to the formData instance.
Here, the uri argument to uploadImageAsync is passed as a route parameter from the previous screen.
const postShoutHandler = async () => {
setShoutUploadStatus("Started Upload");
const response = await uploadImageAsync(route.params.captures);
const uploadResult = await response.json();
if (uploadResult === "Upload successful") {
setShoutUploadStatus("Success");
navigation.navigate("Home");
} else {
setShoutUploadStatus("Failed");
}
};
/* <--Upload image function --> */
const uploadImageAsync = (uri: string) => {
const apiUrl = "https://www.yourserver.com/image";
let uriParts = uri.split(".");
let fileType = uriParts[uriParts.length - 1];
let formData = new FormData();
formData.append("img", {
uri,
name: `photo.${fileType}`,
type: `image/${fileType}`,
});
formData.append("description", "HEY");
let options = {
method: "POST",
body: formData,
headers: {
Accept: "application/json",
"Content-Type": "multipart/form-data",
Authorization: "Bearer " + accessToken,
},
};
return fetch(apiUrl, options);
};
/* <--Upload image function --> */
Here is the Image configuration.
const photoData = await camera.takePictureAsync({
base64: true,
exif: false,
});

Node js App integration with power bi rest Api

Is there a way using power bi rest API in node js, I watched video ,Ran Breuer and Arina Hantsis were showing the demo here,Setting up and Getting Started with Power BI Embedded I want to achieve same but using node js, in our development environment we do not use c#.
I found the Node SDK but it saying we no longer support node SDK,Node SDK
Do I have to change development structure from Node js to c# in order to use power bi Rest API!!
If you want to achieve same, what Ran Breuer and Arina Hantsis demonstrate in there video!
you can use these codes...
after reading the documentation, I come up with this solution it took me 5 days to figure out, anyway I am posting here so everyone can have easy access to codes.
**AppOwnData Power bi embedded reports **
Controller.js
const request = require('request');
const getAccessToken = function () {
return new Promise(function (resolve, reject) {
const url = 'https://login.microsoftonline.com/common/oauth2/token';
const username = ''; // Username of PowerBI "pro" account - stored in config
const password = ''; // Password of PowerBI "pro" account - stored in config
const clientId = ''; // Applicaton ID of app registered via Azure Active Directory - stored in config
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
const formData = {
grant_type: 'password',
client_id: clientId,
resource: 'https://analysis.windows.net/powerbi/api',
scope: 'openid',
username: username,
password: password
};
request.post({
url: url,
form: formData,
headers: headers
}, function (err, result, body) {
if (err) return reject(err);
const bodyObj = JSON.parse(body);
resolve(bodyObj.access_token);
});
});
};
const getReportEmbedToken = function (accessToken, groupId, reportId) {
return new Promise(function (resolve, reject) {
const url = 'https://api.powerbi.com/v1.0/myorg/groups/' + groupId + '/reports/' + reportId + '/GenerateToken';
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + accessToken
};
const formData = {
'accessLevel': 'view'
};
request.post({
url: url,
form: formData,
headers: headers
}, function (err, result, body) {
if (err) return reject(err);
const bodyObj = JSON.parse(body);
resolve(bodyObj.token);
});
});
};
module.exports = {
embedReport: function (req, res) {
getAccessToken().then(function (accessToken) {
getReportEmbedToken(accessToken, req.params.groupId, req.params.reportId).then(function (embedToken) {
res.render('index', {
reportId: req.params.dashboardId,
embedToken,
embedUrl: 'https://app.powerbi.com/reportEmbed?reportId=' + req.params.reportId + '&groupId=' + req.params.groupId
});
}).catch(function (err) {
res.send(500, err);
});
}).catch(function (err) {
res.send(500, err);
});
}
};
Your router index.js
const express = require('express'),
router = express.Router(),
mainCtrl = require('../controllers/MainController');
router.get('/report/:groupId/:reportId', mainCtrl.embedReport);
module.exports = router;
index.ejs or what ever you like
<!DOCTYPE html>
<html>
<head>
<title>Node.js PowerBI Embed</title>
<link rel="stylesheet" href="/bootstrap/dist/css/bootstrap.min.css" />
<style>
html,
body {
height: 100%;
}
.fill {
min-height: 100%;
height: 100%;
box-sizing: border-box;
}
#reportContainer {
height: 100%;
min-height: 100%;
display: block;
}
</style>
</head>
<body>
<div class="container-fluid fill">
<div id="reportContainer"></div>
</div>
<script src="/jquery/dist/jquery.min.js"></script>
<script src="/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="/powerbi-client/dist/powerbi.js"></script>
<script>
const models = window['powerbi-client'].models;
const config = {
type: 'report',
tokenType: models.TokenType.Embed,
accessToken: '<%- embedToken %>',
embedUrl: '<%- embedUrl %>',
id: '<%- reportId %>'
};
// Get a reference to the embedded dashboard HTML element
const reportContainer = $('#reportContainer')[0];
// Embed the dashboard and display it within the div container.
powerbi.embed(reportContainer, config);
</script>
</body>
</html>
Finally Enjoy
localhost:4000/report/put your group id here / put you report id here
I used #Joyo Waseem codes and successfully embedded the report, then I give a try to embed Dashboard and it works too, I decided to post my codes here so anyone who tries to embed Dashboard can use these codes.
Embedded Dashboard using power bi Res API
Controler.js
const request = require('request');
const getAccessToken = function () {
return new Promise(function (resolve, reject) {
const url = 'https://login.microsoftonline.com/common/oauth2/token';
const username = ''; // Username of PowerBI "pro" account - stored in config
const password = ''; // Password of PowerBI "pro" account - stored in config
const clientId = ''; // Applicaton ID of app registered via Azure Active Directory - stored in config
const headers = {
'Content-Type': 'application/x-www-form-urlencoded'
};
const formData = {
grant_type: 'password',
client_id: clientId,
resource: 'https://analysis.windows.net/powerbi/api',
scope: 'openid',
username: username,
password: password
};
request.post({
url: url,
form: formData,
headers: headers
}, function (err, result, body) {
if (err) return reject(err);
const bodyObj = JSON.parse(body);
resolve(bodyObj.access_token);
});
});
};
const getEmbedToken = function (accessToken, groupId, dashboardId) {
return new Promise(function (resolve, reject) {
const url = 'https://api.powerbi.com/v1.0/myorg/groups/' + groupId + '/dashboards/' + dashboardId + '/GenerateToken';
const headers = {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + accessToken
};
const formData = {
'accessLevel': 'View'
};
request.post({
url: url,
form: formData,
headers: headers
}, function (err, result, body) {
if (err) return reject(err);
const bodyObj = JSON.parse(body);
resolve(bodyObj.token);
});
});
};
module.exports = {
prepareView: function(req, res) {
getAccessToken().then(function(accessToken) {
console.log(req.params.groupId);
getEmbedToken(accessToken, req.params.groupId, req.params.dashboardId).then(function(embedToken) {
res.render('index', {
dashboardId: req.params.dashboardId,
embedToken,
embedUrl: 'https://app.powerbi.com/dashboardEmbed?dashboardId=' + req.params.dashboardId + '&groupId=' + req.params.groupId
});
});
});
}
};
index.js
const express = require('express'),
router = express.Router(),
mainCtrl = require('../controllers/MainController');
router.get('/dashboard/:groupId/:dashboardId', mainCtrl.prepareView);
module.exports = router;
index.ejs etc.
<!DOCTYPE html>
<html>
<head>
<title>Node.js PowerBI Embed</title>
<link rel="stylesheet" href="/bootstrap/dist/css/bootstrap.min.css" />
<style>
html,
body {
height: 100%;
}
.fill {
min-height: 100%;
height: 100%;
box-sizing: border-box;
}
#dashboardContainer {
height: 100%;
min-height: 100%;
display: block;
}
</style>
</head>
<body>
<div class="container-fluid fill">
<div id="dashboardContainer"></div>
</div>
<script src="/jquery/dist/jquery.min.js"></script>
<script src="/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="/powerbi-client/dist/powerbi.js"></script>
<script>
const models = window['powerbi-client'].models;
const config = {
type: 'dashboard',
tokenType: models.TokenType.Embed,
accessToken: '<%- embedToken %>',
embedUrl: '<%- embedUrl %>',
id: '<%- dashboardId %>'
};
// Get a reference to the embedded dashboard HTML element
const dashboardContainer = $('#dashboardContainer')[0];
// Embed the dashboard and display it within the div container.
powerbi.embed(dashboardContainer, config);
</script>
</body>
</html>
#Jo Joy what is the seen you should know .
https://github.com/Microsoft/PowerBI-Node/issues/40
It about priorities these company decide in which project they do .
They can response very well about this. But as far as discussion there are no such plan to do so . You can access api before feb 2017 .
If newer api you have to try it for your . May be you folk it . We as commundity will contribute .
They no longer support the Node SDK, but have you tried it? It might still be working. You are gonna want some sort of SDK - it seems that is not the easiest API to work with.

Resources