Nativescript bind value inside image-picker function - javascript

I am using image-picker plugin. I can open images gallery and select single or multiple images.
My problem is how to bind the path of the image to the xml image src?! It doesn't work inside getImage() function.
xml:
<Image class="imageSource" src="{{ thumb }}" stretch="none" />
typescript:
import { Observable } from 'data/observable';
import * as imagepicker from "nativescript-imagepicker";
var counter = 0;
var fs = require('file-system');
export class AssistenceViewModel extends Observable {
thumb:any;
public addImage(){
dialogs.action({
message: "Opções",
cancelButtonText: "Cancelar",
actions: ["Câmera", "Galeria"]
}).then(result => {
console.log("Dialog result: " + result);
if(result == "Câmera"){
//Do action1
console.log("Abrir camera");
}else if(result == "Galeria"){
console.log("Abrir galeria");
let context = imagepicker.create({
mode: "single"
});
context.authorize().then(function() {
return context.present();
}).then(function(selection) {
selection.forEach(function(selected){
selected.getImage().then(function(imagesource){
var localPath = null;
if(platformModule.device.os === "Android"){
localPath = selected.android;
console.log("localPath android: " +localPath);
}else {
// selected_item.ios for iOS is PHAsset and not path - so we are creating own path
let folder = fs.knownFolders.documents();
let path = fs.path.join(folder.path, "Test" + counter + ".png");
let saved = imagesource.saveToFile(path, "png");
localPath = path;
console.log("localPath iOS: " +localPath);
}
if(localPath){
this.thumb = localPath // this is not working
console.log("thumb: "+this.thumb); // this is not working
}
});
});
}).catch(function(e) {
console.log(e);
});
}
});
}
}
The result for console.log("localPath android: " +localPath);
localPath android: /storage/emulated/0/DCIM/Camera/IMG_20171213_224917038.jpg
but I cannot get any log for this.thumb.

You should either use TS arrow functions to preserve the context of this of "cache the meaning of this"
e.g. for arrow functions
// more code above this line
.then(() => {
return context.present();
}).then((selection) => {
selection.forEach((selected) => {
selected.getImage().then((imagesource) => {
Or that = this; pattern
var that = this;
// ... your code in the promises follows
that.thumb = newValue;

Related

Find first file with given filename

Hello I am trying to find first file with given filename ( piece of filename ).
It works fine but it take a while to take result
There is code
const fs = require("fs");
const dirCheckIn =
"\\\\192.168.2.4\\Photos";
exports.checkUploadedFiles = (req, res) => {
let fileName = req.params.filename;
const getAllFiles = function (dirPath, arrayOfFiles) {
files = fs.readdirSync(dirPath);
arrayOfFiles = arrayOfFiles || [];
files.forEach(function (file) {
if (fs.statSync(dirPath + "/" + file).isDirectory()) {
arrayOfFiles = getAllFiles(dirPath + "/" + file, arrayOfFiles);
} else {
arrayOfFiles.push(file);
}
});
return arrayOfFiles;
};
const uploadedFiles = getAllFiles(inventDirCheckIn);
console.log(uploadedFiles)
let result = uploadedFiles.find(
(result) => result.startsWith(fileName));
if (!result) {
res.send('nothing found')
} else if (result) {
res.send(result)
}
}
It works fine but for example if I have over 7000 photos it takes about 5 sec to get result.
Maybe there is smarter solution?
How can I make it in better way? I want to check if file is uploaded into dir Photos.
I got simple api route /api/getUploadedFiles/:filename
Also I want use startsWith because sometimes I do not know full name of file
/**
*
* #param filePath path to file which is to be checked if it exists.
*/
private checkFileExistsSync(filePath: string) {
let flag = true;
try {
fs.accessSync(filePath, fs.constants.F_OK);
} catch (e) {
flag = false;
}
return flag;
}
// Example usage
// path to the file
const dirCheckIn =
"\\\\192.168.2.4\\Photos";
if (checkFileExistsSync(dirCheckIn)) {
// if the file exists do something...
}
if (!checkFileExistsSync(dirCheckIn)) {
// if the file doesn't exists do something...
}

Is this possible with Gulp? Gulp Change Text and Dest

I don't know what this is possible.
files
a.html / b.hml
c.css / d.css
There are two changes in Html and Css
Each HTML has a changed Css(c.css,d.css).
The path of Css is as follows
<link src="/style/sample/c.css">
If a Css file has been changed, verify that the CSS file has been declared in the changed HTML.
Change the path of the css file.
Create a new file using Gulf's dest.
That's my code here.
async function ds(cd) {
const branch = branchName.replace("/", "-");
let fileHtml = [],
fileCSS = [],
fileImage = [];
// npm package git-status,
// Look for files that are up on git stage.
await gitStatus((err, data) => {
data.map((e) => {
item = e.to.replace("WebContent/resources", "./resources"); // change path
// Check only Resources
if (item.indexOf("./resources/") !== -1) {
if (item.indexOf("html") !== -1) {
fileHtml.push(item); // get Html List T^T
return fileHtml;
}
if (item.indexOf("css") !== -1) {
// css
fileCSS.push(item);
return fileCSS;
}
if (item.indexOf("img") !== -1) {
// img
fileImage.push(item);
return fileImage;
}
}
});
cd();
});
//I think it's possible with JavaScript, but I don't know what to do with Gulp.
fileHtml.forEach((e) => {
let files = fs.readFileSync(__dirname + e, "utf8"); //해당 HTML 파일
let splitFile = files.split(/\r?\n/);
// 각각의 HTML 파일 내부에서
let result = splitFile.forEach((j, i) => {
// 위에서 찾은 css 파일이 있는지 찾아서
fileCSS.forEach((v) => {
if (j.indexOf(v) >= 0) {
let result = j.replace("/resources/", "/" + branch + "/");
console.log(result);
// console.log("페이지는", e);
// console.log("파일은", v);
}
});
});
});
}

Unhandled expression at line :

So i am playing around with Babylon. In a createScene function I am also loading the AssetManager.
Whenever i add a task, it will throw errors: unhandled expression 1 for every line of my HTML document.
This also happens, if I ignore my assetManager and put in SceneLoader.ImportMesh instead.
I really dont know what to do anymore.
Thats my assetManager:
function assetManager() {
var assetsManager = new BABYLON.AssetsManager(scene);
var meshTask = assetsManager.addMeshTask("baum", "", "assets/", "carAcura.obj");
meshTask.onSuccess = function (task) {
task.loadedMeshes[0].position = BABYLON.Vector3.Zero();
engine.loadingUIText = "Loaded asset " + task.loadedMeshes[0].name;
console.log(task.loadedMeshes[0].name);
}
assetsManager.onTaskError = function (task) {
console.log("error on Loading" + task.name);
}
assetsManager.load();
assetsManager.onFinish = function (tasks) {
console.log("done");
engine.runRenderLoop(function () {
if (engine.webGLVersion === 1) {
pixiRenderer.reset();
}
scene.render();
engine.wipeCaches(true);
pixiRenderer.reset();
pixiRenderer.render(stage);
divFps.innerHTML = engine.getFps().toFixed() + " FPS";
//loop();
});
};
};

How can I fix error "_helpers.pageUrl is not a function:" in my KeystoneJS project?

I have guide website and I want to add some tours there.
I created two models: Tour.js and TourCategory.js (similar to Post.js and PostCategory.js). Then I had to create two routes: tours.js and tour.js (also similar for posts). When I was adding helpers I caught error: _helpers.pageUrl is not a function
How can I fix it?
I have tried to find if anybody has the same problem but found nothing.
I have no idea how to fix it because I did not change anything in my code (helpers/index.js) before adding my new helpers.
My helpers/index.js fragment:
_helpers.tourUrl = function (categorySlug, tourSlug, options) {
return ('/tours/' + categorySlug + tourSlug);
};
_helpers.categoryUrl = function (categorySlug, options) {
return ('/tours/' + categorySlug);
};
_helpers.paginationNavigation = function (pages, currentPage, totalPages, options) {
var html = '';
_.each(pages, function (page, ctr) {
var pageText = page;
var isActivePage = ((page === currentPage) ? true : false);
var liClass = ((isActivePage) ? ' class="active"' : '');
if (page === '...') {
page = ((ctr) ? totalPages : 1);
}
var pageUrl = _helpers.pageUrl(page);
html += '<li' + liClass + '>' + linkTemplate({ url: pageUrl, text: pageText }) + '</li>\n';
});
return html;
}
I expected that page will load without any errors.
Because of in your helper file you don't make any function with the name pageUrl and try to access in another function_helpers.pageUrl().
You need to add a function (if not exist ) with the name pageUrl like this
const _helpers = {};
_helpers.pageUrl = (input) => {
try {
// ... Your business logic
return true; // It's up to you
} catch (err) {
console.log(err);
throw err;
}
};
module.exports = _helpers

HTML5 ondrop event returns before zip.js can finish operations

The crux of my issue is that I need to use a datatransferitemlist asynchronously which is at odds with the functionality described in the specs, which is that you are locked out of the dataTransfer.items collection once the event ends.
https://bugs.chromium.org/p/chromium/issues/detail?id=137231
http://www.whatwg.org/specs/web-apps/current-work/multipage/dnd.html#drag-data-store
The case offender is the following. With a more detailed description of my problem and thoughts below it.
drophandler: function(event) {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
zip.workerScriptsPath = "../bower_components/zip.js/WebContent/";
zip.useWebWorkers = false; // Disabled because it just makes life more complicated
// Check if files contains just a zip
if (event.dataTransfer.files[0].name.match(/(?:\.([^.]+))?$/) == 'zip') {
var reader = new FileReader();
that = this;
reader.onload = function(e) {
that.fire('zipuploaded', e.target.result.split(',')[1]);
}
reader.readAsDataURL(event.dataTransfer.files[0]);
// Rev up that in browser zipping
} else {
var that = this;
var items = event.dataTransfer.items;
// Async operation, execution falls through from here
zip.createWriter(new zip.Data64URIWriter(), function(writer) {
(function traverse(list, path, i, depth) {
return new Promise(function(resolve, reject) {
var item;
if (depth == 0) {
if (i == list.length) {
writer.close(function(uri) {
that.fire('zipuploaded', uri.split(',')[1]); // Just the base64, please
fulfill(1);
return;
});
} else {
console.log(i);
console.log(list);
var item = list[i].webkitGetAsEntry();
}
} else {
if (i == list.length) {
resolve(0);
return;
} else {
item = list[i];
}
}
if (item.isFile) {
item.file(function(file) {
// Zipping operations done asynchronously, it'll fail by roughly the second operation
writer.add(path + file.name, zip.BlobReader(file), function() {
traverse(list, path, i + 1, depth).then(resolve(0)); // Next item
});
});
} else if (item.isDirectory) {
var dirReader = item.createDirReader();
dirReader.readEntries(function(entries) {
// Operate on child folder then the next item at this level
traverse(entries, path + item.name + "/", 0, depth + 1).then(function() {
traverse(list, path, i + 1, depth).then(resolve(0));
});
});
}
});
})(items, "", 0, 0); // Begin with datatransferitemlist, 0th element, depth 0
});
this.$.uploadarea.classList.remove('highlightdrag');
}
// When we exit it kills the event.dataTransfer.items
},
I am using zip.js which is asynchronous with the HTML5 DnD API.
The ondrop event ends before the asynchronous zip.createWriter/writer.add operations finish. I can think of four ways to solve this although I don't know how to implement any of them and would like some advice.
Block until createWriter is done. (Blocking javascript? Uhoh)
Prevent the ondrop from locking me out of dataTransfer.items (It seems to be for security so unlikely)
Synchronously copy out the contents of dataTransfer.items first (Probably very slow)
Do everything synchronously (Don't think zip.js allows this, JsZip does, but I moved away from that due to it having its own limitations with large file sets)
HTML5 DnD works as expected. The problem is, when adding multiple files, if you add a file before previous finish, zip.js breaks silently. This can be fixed by calling writer.add in series.
The snippet might not work, see this pen instead.
This example flats the structure of dropped files, then add it to zip in series.
function mes(it) {
const m = document.querySelector('#mes')
return m.textContent = it + '\n' + m.textContent
}
function read(items) {
return Promise.all(items.map(item => {
if (item.isFile) return [item]
return new Promise(resolve => item.createReader().readEntries(resolve))
.then(entries => {
entries.forEach(it => it.path = item.path + '/' + it.name)
return read(entries)
})
})).then(entries => entries.reduce((a, b) => a.concat(b)))
}
function handleResult(blob){
const res = document.querySelector('#result')
res.download = 'files.zip'
res.href = window.URL.createObjectURL(blob)
res.textContent = 'download zipped file'
}
function handleItems(items){
mes(items.length)
items.forEach(item => item.path = item.name)
const initZip = new Promise(resolve =>
zip.createWriter(new zip.BlobWriter, resolve)
)
const getFiles = read(items).then(entries => {
return Promise.all(entries.map(entry =>
new Promise(resolve =>
entry.file(file => {
file.path = entry.path
resolve(file)
})
)
))
})
return Promise.all([getFiles, initZip]).then(([files, writer]) =>
files.reduce((current, next) =>
current.then(() =>
new Promise(resolve => {
mes(next.path)
writer.add(next.path, new zip.BlobReader(next), resolve)
})
)
, Promise.resolve())
.then(() => writer.close(handleResult))
)
}
zip.useWebWorkers = false
const drop = document.querySelector('#drop');
['dragover', 'drop'].forEach(name =>
drop.addEventListener(name, ev => ev.preventDefault())
)
drop.addEventListener('drop', ev => {
const items = [].slice.call(ev.dataTransfer.items)
.map(item => item.webkitGetAsEntry())
return handleItems(items)
})
html, body, #drop {
height: 100%;
width: 100%;
}
<script src="http://gildas-lormeau.github.io/zip.js/demos/zip.js"></script>
<script src="http://gildas-lormeau.github.io/zip.js/demos/deflate.js"></script>
<div id="drop">
Drop here!
<br>
<a id="result"></a>
</div>
<pre id="mes"></pre>
jszip is much easier than this, you might want to give it a try.

Categories

Resources