I am getting error 'PptxGenJS is not a constructor' - angular8

I am trying to use PptxGenJS.
I installed it by npm install pptxgenjs --save
I created very simple function, according to the examples.
When I am doing:
import * as PptxGenJS from 'pptxgenjs';
const pptx = new PptxGenJS();
I am getting error "pptxgenjs__WEBPACK_IMPORTED_MODULE_2__ is not a constructor"
When I am doing:
let PptxGenJS = require("pptxgenjs");
let pptx = new PptxGenJS();
I am getting the error: "TypeError: PptxGenJS is not a constructor"
I am using 3.0.1 with Angular8 on Ubuntu

I faced same issue. Import correct file, then it should work,
import pptxgen from "pptxgenjs";
let pres = new pptxgen();
let slide = pres.addSlide();
let textboxOpts = { x: 1, y: 1, w: '80%', h: 0.5, align: 'center', color: '131A1A', fill: 'B2E8ED', fontSize: 20 };
slide.addText("Sample text", textboxOpts);
pres.writeFile("Sample Presentation.pptx");

make sure to allow synthetic default imports and esModule interoperability in your tsconfig file:
"angularCompilerOptions": {
...
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
}
then import in into your component like this:
import PptxGenJS from 'pptxgenjs'
use like this:
ppt = new PptxGenJS();

I find out that using pptxgenjs-angular works fine.
What I done is:
import * as PptxGenJS from 'pptxgenjs-angular';
const pptx = new PptxGenJS();
For some unknown reason, PptxGenJS failed to find the JSZip.
So I create ZIP object in my function, and send it as new parameter to
const JSZip = require('jszip');
var zip = new JSZip();
pptx.save(fileName, null, null, zip);

Related

Vuejs3 external library undefined funtion

I am currently working on a Vuejs3 application with the fabricjs library added.
Now I am trying to add an external library called fabricPublisherTools in the application. But the method/function "_registerSnaps" that is being called is somehow "undefined".
The external library gives me the following working example.
<script type="module">
import {fabricAddSnapper,fabricAddSmartGuides} from 'https://cdn.jsdelivr.net/gh/mtrudw/fabricPublisherTools/dist/fabricPublisherTools.min.js';
fabricAddSnapper();
fabricAddSmartGuides();
var canvas = new fabric.Canvas('c4');
var rect = new fabric.Rect({left: 100,top:100,width:150,height:100,fill:'blue'});
var rect2 = new fabric.Rect({left: 500,top:500,width:150,height:100,fill:'green'});
var rect3 = new fabric.Rect({left: 400,top:200,width:150,height:100,fill:'yellow'});
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
rect.doesSnap();
rect2.doesSnap();
rect3.doesSnap();
canvas.add(rect,rect2,rect3);
</script>
The way I implemented in Vuejs3 is as follows:
<script setup>
import { onMounted } from "vue"
import { fabric } from 'fabric';
import {fabricAddSmartGuides,fabricAddSnapper,fabricAddUndoRedo} from 'https://cdn.jsdelivr.net/gh/mtrudw/fabricPublisherTools/dist/fabricPublisherTools.min.js';
let canvas;
const setupEditor = () => {
fabricAddSnapper();
fabricAddSmartGuides();
canvas = new fabric.Canvas('canvas');
canvas.setHeight(500);
canvas.setWidth(500);
canvas.backgroundColor = "#f00";
canvas.setDimensions({width: 500, height: 500});
var rect = new fabric.Rect({left: 100,top:100,width:150,height:100,fill:'blue'});
var rect2 = new fabric.Rect({left: 500,top:500,width:150,height:100,fill:'green'});
var rect3 = new fabric.Rect({left: 400,top:200,width:150,height:100,fill:'yellow'});
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
rect.doesSnap();
rect2.doesSnap();
rect3.doesSnap();
canvas.add(rect,rect2,rect3);
canvas.renderAll();
}
onMounted(() => {
setupEditor()
})
</script>
It gives me the following error when I try to run it:
Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'bind')
And its about this line:
canvas._registerSnaps(canvas._getSmartGuides.bind(canvas));
When I console log "_registerSnaps" I see it's undefined which means something has not been appended/added by the library.
I just don't know if I did something wrong when I imported the library that caused the problem.
What exactly am I doing wrong?
Thank you in advance.
If bind is what's undefined, have you checked if your problem is with _getSmartGuides since that is what calls the bind() function?
You'll need to call fabricAddSmartGuides();
purely from reading the (fabricPublisherTools) source: _getSmartGuides is created in fabricAddSmartGuides(). Do you / where do you call fabricAddSmartGuides ?

HERE Maps JS API 3.1.30.17 used in VUE - Error for style group 'non-collision' in Firefox

I've build a simple Here Map using Vue 2 and the JS API in version 3.1.30.17. The map works fine in all browsers except Firefox v102.
This is the error message in Firefox:
Tangram [error]: Error for style group 'non-collision' for tile 20/7/68/41/7 CanvasRenderingContext2D.drawImage: Passed-in canvas is empty: loadTexture#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:417267
e/sn.addWorker/<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:63015
EventListener.handleEvent*e/sn.addWorker#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:62515
e/value/<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:515089
value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:515502
value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:514847
e/value/this.initializing<#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:511497
promise callback*value#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:431:511472
Ul#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:335:441
p.eh#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:378:446
p.Ge#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:329:436
p.Ge#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:376:356
S#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:369:214
T.prototype.u#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:410:166
T#https://js.api.here.com/v3/3.1.30.17/mapsjs-core.js:401:290
... The error is even bigger
The following method I'm using to init Here Maps inside Vue's mounted:
async initializeHereMap() {
const mapContainer = this.$refs.hereMap;
const H = window.H;
// Initialize the platform object:
this.platform = new H.service.Platform({
apikey: this.apiKey,
});
await this.geocode(this.platform, this.originAddress)
.then(data => this.routingParameters.origin = data[0]);
await this.geocode(this.platform, this.destinationAddress)
.then(data => this.routingParameters.destination = data[0]);
// Obtain the default map types from the platform object
const defaultLayers = this.platform.createDefaultLayers({
lg: window.navigator.language,
});
// Instantiate (and display) a map object:
const map = new H.Map(mapContainer, defaultLayers.vector.normal.map, {
zoom: this.zoom,
center: this.center,
padding: {
top: this.padding,
bottom: this.padding,
left: this.padding,
right: this.padding,
},
});
// create map pins
const mapPinOrigin = this.addMapPin('A', 40);
const mapPinDestination = this.addMapPin('B', 40);
let linestring = new H.geo.LineString();
linestring.pushPoint(this.routingParameters.origin);
linestring.pushPoint(this.routingParameters.destination);
// Create a polyline to display the route:
let routeLine = new H.map.Polyline(linestring, {
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
});
// Create a marker for the start point:
let startMarker = new H.map.Marker(this.routingParameters.origin, { icon: mapPinOrigin });
// Create a marker for the end point:
let endMarker = new H.map.Marker(this.routingParameters.destination, { icon: mapPinDestination });
// Add the route polyline and the two markers to the map:
map.addObjects([routeLine, startMarker, endMarker]);
// Set the map's viewport to make the whole route visible:
map.getViewModel().setLookAtData({bounds: routeLine.getBoundingBox()});
// add behavior control
if (this.behaviors) new H.mapevents.Behavior(new H.mapevents.MapEvents(map));
// add UI
if (this.controls) H.ui.UI.createDefault(map, defaultLayers);
},
Is there some one facing the same issue and could solved it?
Did you follow this example on: https://developer.here.com/tutorials/how-to-implement-a-web-map-using-vuejs/ ?
Tangram error is related to rendering e.g. when render map objects (like icons, markers, polylines etc.) and map vector tiles.
I don't think so that this issue related to HERE JS Map API.
Because all examples on https://developer.here.com/documentation/examples/maps-js are working well on my FireFox 102.0.1
It could be some map objects like icons or markers etc. are created in some moment but is not finished yet and then try to push onto map? Creating an icon in some asynchron function?
Or in like your code:
await this.geocode(this.platform, this.originAddress)
.then(data => this.routingParameters.origin = data[0]);
You don't know when func geocode will be finished (e.g. due slow internet connectivity)
It could be this command above is not done yet, but your code is already start to run this code:
linestring.pushPoint(this.routingParameters.origin);<-- 'this.routingParameters.origin' could be null
linestring.pushPoint(this.routingParameters.destination);
// Create a polyline to display the route:
let routeLine = new H.map.Polyline(linestring, { <-- Could cause Tangram error because 'linestring' is strange due undefined origin yet!
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
});
The polyline options is not correct in:
new H.map.Polyline(linestring, {
linestring,
style: { strokeColor: '#3F80C4', lineWidth: 5 },
}
Why in above the 'linestring' is second time in options?
Please follow correct syntax on:
https://developer.here.com/documentation/maps/3.1.31.0/api_reference/H.map.Polyline.html#.Options

I am trying to load a texture onto a Sphere in Nuxt using Three

I am trying to add a texture to a sphere, specifically by mapping an image to it using TextureLoader.
However, I can add the material perfectly fine, without the image that is. For example, if I removed the line "map: TextureLoader().load(earthUV)" and replaced it with "color: 0xFF0000", the sphere would load perfectly fine with no errors, but with the TextureLoader I just receive the error log found below.
Please feel free to ask questions as I do not know what else I should provide to help fix this error.
Error Log:
TypeError: Cannot set properties of undefined (setting 'manager')
at Loader (three.module.js?5a89:34164:1)
at TextureLoader (three.module.js?5a89:34947:1)
at VueComponent.mounted (about.vue?9043:39:1)
at invokeWithErrorHandling (vue.runtime.esm.js?2b0e:1863:1)
at callHook (vue.runtime.esm.js?2b0e:4235:1)
at Object.insert (vue.runtime.esm.js?2b0e:3158:1)
at invokeInsertHook (vue.runtime.esm.js?2b0e:6390:1)
at Vue.patch [as __patch__] (vue.runtime.esm.js?2b0e:6538:1)
at Vue._update (vue.runtime.esm.js?2b0e:3960:1)
at Vue.updateComponent (vue.runtime.esm.js?2b0e:4075:1)
Please find the code for my attempt below:
<template>
<div>
<canvas ref="aboutCanvas"></canvas>
</div>
</template>
<script>
import {
Scene,
PerspectiveCamera,
WebGLRenderer,
Mesh,
SphereGeometry,
MeshBasicMaterial,
TextureLoader,
} from "three";
import earthUV from "~/assets/earthUV.jpg";
export default {
mounted() {
const scene = new Scene();
const camera = new PerspectiveCamera(
75,
innerWidth / innerHeight,
0.1,
1000
);
const renderer = new WebGLRenderer({
canvas: this.$refs.aboutCanvas,
});
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
// Create a sphere
const sphere = new Mesh(
new SphereGeometry(5, 50, 50),
new MeshBasicMaterial({
map: TextureLoader().load(earthUV)
})
);
// Add objects into scene
scene.add(sphere);
camera.position.z = 10;
function animate() {
requestAnimationFrame(animate);
renderer.render(scene, camera);
}
animate();
},
};
</script>
When creating a TextureLoader, you have to use the new keyword. You can use that single TextureLoader multiple times to load as many textures as you need.
const texLoader = new TextureLoader();
const sphere = new Mesh(
new SphereGeometry(5, 50, 50),
new MeshBasicMaterial({
map: texLoader.load(earthUV)
})
);

Cannot fit bounds in mapbox-gl , in Vue app

I am using vue 2.6.10 and I have the following dependencies vue-mapbox 0.4.1 and mapbox-gl 1.3.2
The map works, but I cannot get all the points of the map, create bounds and make the map zoom there.
What I am doing now, based on this and this
In my template
<MglMap
ref="map"
#load="mapLoaded()">
and then in my javascript
import Mapbox from "mapbox-gl";
components: { Mapbox}
methods :{
mapLoaded(){
let coords = [];
//coords is array , contains arrays like [-118.578, 51.524]
let bounds = coords.reduce((bounds, coord)=> {
return bounds.extend(coord);
}, this.mapbox.LngLatBounds(coords[0], coords[0])
);
this.$refs['map'].map.fitBounds(bounds, { padding: 20 });
}
},
created(){
this.mapbox = Mapbox;
}
This should work, but I keep getting
TypeError: this.setSouthWest is not a function
so I guess there is a problem in this.mapbox.LngLatBounds(coords[0], coords[0]) , maybe the this.mapbox. or the LngLatBounds does not work.
If I console log the coords[0], prints an array [10.467778, 37.600833]
What am I missing? Thanks
I have got the same error. Turns out I have missed "new" keyword.
You can try adding the "new" keyword for "this.mapbox.LngLatBounds"
The following code worked for me.
import mapboxgl from 'mapbox-gl';
Vue.prototype.$maps = mapboxgl
this.map = new this.$maps.Map({container: 'mapContainer', // container ID
style: 'mapbox://styles/mapbox/streets-v11', // style URL
zoom: 9 // starting zoom
});
const sourceMarker = new this.$maps.Marker().setLngLat(origin).addTo(this.map);
const destMarker = new this.$maps.Marker().setLngLat(destination).addTo(this.map);
const bounds = new this.$maps.LngLatBounds(origin, destination);
this.map.fitBounds(bounds);

SPFX 1.7.1 webpart is not working on IE11

I have created a new SharePoint web part (version 1.7.1). I'm using the react template. The web part is very basic, yet doesn't run on IE 11.
The error returned is
Object doesn't support property or method 'find'
I don't use find in any of my .ts files, so I found the .find method is being called by the .js files that were transpiled from my .ts files.
Can anybody confirm this to be a bug in SPFX v1.7.1?
If so, is there a solution.
I know this could be fixed by introducing a shim, but I don't know how to configure this for SPFX and can't find any documentation that explains how to do this.
Any help is welcome.
If I recall correctly, this is because IE 11 doesn't support Element.closest, which is used by the React engine.
I have personally used element-closest to polyfill it, although I'm sure other options exist.
// beginning of WebPart code file
import 'element-closest/browser';
import * as React from 'react';
import * as ReactDom from 'react-dom';
// rest of the code, etc.
With refer to this article, we can see that the Array.prototype.find() method not support IE browser. But, This method has been added to the ECMAScript 2015 specification and may not be available in all JavaScript implementations yet. However, you can polyfill Array.prototype.find with the following snippet:
// https://tc39.github.io/ecma262/#sec-array.prototype.find
if (!Array.prototype.find) {
Object.defineProperty(Array.prototype, 'find', {
value: function(predicate) {
// 1. Let O be ? ToObject(this value).
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let len be ? ToLength(? Get(O, "length")).
var len = o.length >>> 0;
// 3. If IsCallable(predicate) is false, throw a TypeError exception.
if (typeof predicate !== 'function') {
throw new TypeError('predicate must be a function');
}
// 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
var thisArg = arguments[1];
// 5. Let k be 0.
var k = 0;
// 6. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
// b. Let kValue be ? Get(O, Pk).
// c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
// d. If testResult is true, return kValue.
var kValue = o[k];
if (predicate.call(thisArg, kValue, k, o)) {
return kValue;
}
// e. Increase k by 1.
k++;
}
// 7. Return undefined.
return undefined;
},
configurable: true,
writable: true
});
}
Besides, as far as I know, when we use React, by default, the generated react project supports all modern browsers. Support for Internet Explorer 9, 10, and 11 requires polyfills. You could check it and import related packages.
You can adjust your tsconfig.json file: set "target" to "es5" under "compilerOptions".
Typescript will create polyfills for you.
I had the same issue. Use this import in your webpart.ts file.
import 'core-js/modules/es6.array.find';