set processor in $http PUT request not saving proper data - javascript

Relatively new to javascript and angular. I'm using an elasticsearch instance to ingest/index different files. The webapp should have the capability to allow the user to upload multiple files, which will then be processed using the ingest processor and indexed into ES. I'm using angular-base64-upload to extract the base64 data. The following is what I've tried so far.
The html:
<div ng-switch-when="upload">
...
<input type="file" ng-model="obj.files" name="files"
base-sixty-four-input multiple>
...
<div ng-show="obj.files.length != 0">
<button class="btn btn-primary" type="submit" ng-click="ingest()">
Index All {{obj.files.length}} Files
</button> <br><br>
</div>
</div>
The javascript ingest() function code in my controller:
//Ingesting multiple files
$scope.obj = {files: []};
$scope.ingest = function () {
$scope.obj.files.forEach(function (file){
var fname = file.filename.replace(/\.[^/.]+$/, "");
var fdata = file.base64;
//Creating the pipeline
console.log('filename is: ' + fname);
$http({
url: 'http://192.168.100.30:9200/_ingest/pipeline/attachment',
method: "PUT",
data: {
"description" : "Indexing files",
"processors" : [
{
"set" : {
"field" : "filename",
"value" : fname
},
"attachment" : {
"field" : "data"
}
}
]
}
})
.then(function(allowed){
//Indexing the document
$http({
url: 'http://192.168.100.30:9200/my_index4/my_type/'+fname+'?pipeline=attachment', //unique ID for every document, ensures that there are no overlaps
method: "PUT",
data: {
"data": fdata
}
})
})
})
}
The console logging is just used for debug purposes.
The issue I'm running into is while elastic stores the file under the proper _id, which in my case is the filename, it does not store the proper field: filename. For instance, if I upload 2 files called hello.txt and world.txt, ES will store both files with hello and world as their respective _ids, but the filename field is often swapped or just generally, incorrect. I've ran the code multiple times to see if there was a pattern, and I can't really seem to find one.
The console.logs show that fname is the proper filename before the first http, after it, and after the second http, which is why I'm confused as to why the set processor is not storing it properly.
I may not have clearly explained the issue very well, as it's kind of convoluted. Let me know if anything needs extra explanation. Thanks!

Related

Parsing JSON-like file type to JSON in JavaScript

I have lots of files with an unusual file extension.
I need to read the files using JavaScript and convert their contents to JSON or regular JavaScript objects.
Is this even possible?
I have some hope, because the files are already structured very similar to JSON:
// file.unusualFileType
Page: {
id: P001
Title: "Page Title"
URL: "/home"
Elements: {
Button: {
Text: "Click me"
Action: SAVE
}
}
}
EDIT: Håken Lid kindly provided a solution for my particular use case. Out of curiosity I would still be interested in how to read any file as a string with JavaScript and how one could possible parse such a string.
It would be valid yaml if you strip out the curly brackets. You can use js-yaml to parse the sample data, so maybe it works with the rest of your files too?
const rawData = `
Page: {
id: P001
Title: "Page Title"
URL: "/home"
Elements: {
Button: {
Text: "Click me"
Action: SAVE
}
}
}`
const yamlData = rawData.replace(/[{}]/g, '')
console.log(jsyaml.load(yamlData))
<script src="https://cdnjs.cloudflare.com/ajax/libs/js-yaml/3.13.1/js-yaml.min.js"></script>

How to export json object into excel using javascript or jquery?

I wanted to export my json object into excel file. I have searched in Google and tried the following, but I am unable to get or export my object data into excel file on clicking of button, it is downloading but without any columns/data(i.e empty file is downloading).
I am not sure what is the problem, Please someone help me regarding this. Thanks in advance !
Created Plnkr.
html:
<div id="dvjson"></div>
<br><button type="button" id='DLtoExcel'>
Download CSV
</button>
js:
$(document).ready(function(){
//if I give below json object, file is downloading with the columns/data and hence it is fine
//var testjsondata = [{"number":123}];
//if I give like below object, empty file is downloading, not having any data
//it is not working //it should also work
//var testjsondata = {"number": 123}//it is not working //it should also work
//and the following object format also should work
var testjsondata = {
"test": {
"name": "abc",
"address": [{
"number": "12345",
"street": "xyz"
}]
},
"mynumber": 12
};
var $btnDLtoExcel = $('#DLtoExcel');
$btnDLtoExcel.on('click', function () {
$("#dvjson").excelexportjs({
containerid: "dvjson"
, datatype: 'json'
, dataset: testjsondata
, columns: getColumns(testjsondata)
});
});
console.log(testjsondata);
});
Any other solutions or libraries also welcome, my json object is plain type, not any array type.

How to get Alfresco webscript JSON response in JavaScript file

I'm working on alfresco maven sdk project.
So i have a repo webscript who return a json response template containinng the list of files contained in a specific folder (in my case it's: Espace%20racine/Dictionnaire%20de%20données/Dossier%20Workflow).
The template response.json.ftl is here:
{
"Files" : [
<#list folder.children as child>
<#if child.isDocument>
{
"name" : "${child.name}"
}
<#if child_has_next>,</#if>
</#if>
</#list>
]
}
My webscript works fine, and when i run it through the commande line or the browser, i get a response like:
{
"Files" : [
{
"name" : "test"
}
,
{
"name" : "test2"
}
,
{
"name" : "test3"
}
]
}
Now, i want to invoke my webscript from a javascript file who reside in the folder web of share, but i haven't idea to how achieve this. I searched on the net but i don't find a consistant example to how manage this.
It'll help me lot if anyone can tell me the way to achieve this or take me an example to how achieve this.
Below is the code for making an ajax call in alfresco share.There are other methods also available like Alfresco.util.Ajax.jsonPost,Alfresco.util.Ajax.jsonPut etc..In below console.log(response.json) will print the response in console.
var fnSuccess = function RESPONSE_functionName(response)
{
console.log(response.json)//Here you will get response json.
};
var fnFailure = function RESPONSE_functionName(response)
{
Alfresco.util.PopupManager.displayMessage({text:"Failure"});
};
Alfresco.util.Ajax.jsonGet(
{
url: Alfresco.constants.PROXY_URI + "REPOSITORY_WEBSCRIPT_URL",
successCallback:
{
fn: fnSuccess,
scope: this
},
failureCallback:
{
fn: fnFailure,
scope: this
}
});

Node.js: How to write input values of a formular into a JSON file when the submit button is pressed?

NEW: MORE SPECIFIC DESCRIPTION
I'm programming a website with different products of different types. Each product has a detail page with a comment function. The path of a products detail site looks like http://localhost:3000/details/type/name. When a user fills the form to write a comment and presses the submit button, all data should be append to the product type's JSON file which looks like:
type1.json
[
{
"name": "Product1",
"description": "Description1",
"comments":[
{
"user": "Matthew",
"message": "Very Good!",
"timestamp": "2017-03-17T17:51Z"
},{
"user": "Lea",
"message": "Nice",
"timestamp": "2017-03-10T13:29Z"
}
]
},
{
"name": "Product2",
"description": "Description2",
"comments":[
{
"user": "Ann",
"message": "This is very useful!",
"timestamp": "2017-02-02T19:30Z"
},{
"user": "Tim",
"message": "Awesome",
"timestamp": "2017-04-01T20:25Z"
}
]
]
This is the part of my HTML file which contains the form:
details.html
<form action="" method="POST" id="commentForm">
<div class="form-group">
<input type="text" id="name"
placeholder="Name" class="form-control" name="name"/>
</div>
<div class="form-group">
<textarea cols="30" rows="5" class="form-control" id="message" placeholder="Message" name="message"></textarea>
</div>
<div class="form-group">
<div class="col-md-6 text-center">
<button type="reset" class="btn btn-default">
<span class="glyphicon glyphicon-remove"></span>
Reset
</button>
</div>
<div class="col-md-6 text-center">
<button type="submit" class="btn btn-success">
<span class="glyphicon glyphicon-ok"></span>
Send
</button>
</div>
</div>
</form>
This is the relevant part of my JavaScript file:
details.js
$(function () {
$.fn.serializeObject = function()
{
var o = {};
var a = this.serializeArray();
$.each(a, function() {
if (o[this.name] !== undefined) {
if (!o[this.name].push) {
o[this.name] = [o[this.name]];
}
o[this.name].push(this.value || '');
} else {
o[this.name] = this.value || '';
}
});
return o;
};
$("#commentForm").bind("submit", function(evt) {
console.log(JSON.stringify($("#commentForm").serializeObject()));
$.ajax({
url: window.location.pathname,
type: "POST",
contentType: "application/json",
data: JSON.stringify($("#commentForm").serializeObject()),
success: function(data) {
console.log('success');
console.log(JSON.stringify(data));
},
});
return false;
});
});
Now, the question is: What to write in the app.js?
In the following is an excerpt of the current app.js.
app.js
const express = require("express");
const app = express();
const fs = require('fs');
const path = require("path");
const jsonfile = require('jsonfile');
const bodyParser = require('body-parser');
app.use(bodyParser.json());
const type1File = __dirname + "/data/type1.json";
...
app.post("/details/:typ/:name", function (req, res) {
if (req.params.typ == "type1") {
const apps = readJsonFile(type1File);
res.send(getProduct(apps, req));
???What to write here???
}
...
});
function readJsonFile(file) {
try {
const data = fs.readFileSync(file);
return JSON.parse(data);
} catch (e) {
console.log(file + "could not be read. " + e);
return [];
}
}
What should I add? How is it possible that the data will be written to the "comment"-key of the right JSON object? Please help me, I spent a lot of time trying out different things, but nothing works right.
Note: This answer was written before the question was rewritten:
https://stackoverflow.com/posts/43213085/revisions
This question is so general that it's hard to give you any specific answer. But if you want persistent data in your app then you should use a database.
Some databases like Mongo, Postgres or Redis need to be run as standalone application either on the same or on a different server. Some embedded databases like SQLite don't need a standalone process and can be run directly in your application. There are multiple choices of databases and it's something that you have to choose yourself for your particular case. But you should choose some database to store the data.
It's not that it is impossible to write to JSON files on updates and then read those files as needed, but the amount of work that you'd have to do to synchronize the access to the data so that no two requests to write happen at the same time and no read happens while a write is in progress, all that without accidentally blocking the event loop in the process and handling multiple requests concurrently, is something greatly more difficult than just using any database as intended.
Some databases like Mongo will let you store any JSON documents (actually it stores BSON but for the user it's just like JSON). Using a document database like Mongo or CouchDB will be most similar to having JSON files but using a relational database could work as well. Pretty much every persistent data is kept in databases. If you can write your own database that stores data in JSON files then by all means do it if you need, but if you can't then just use the right tool for the job.
That having been said, if you still insist on reading and writing JSON files, here's what to do:
To write data as JSON into files, you will need to use JSON.stringify() and fs.writeFile().
To read JSON data from files, you will need to use fs.readFile() and JSON.parse().
Things to keep in mind:
JSON.parse() and JSON.stringify() must always be wrapped in a try/catch block or otherwise your app will crash (or use tryjson module from npm).
Never use methods of the fs modules with "Sync" in their name or otherwise your app will be blocked from serving requests.
You need to implement locking and synchronization of the access to files or otherwise your data will get corrupted - this is the most difficult and most important part, and this is the reason why people use databases for that sort of things.

YII2. Using URL's in js

I have the following javascript code
$(".order-event-btn").click(function(e) {
$.ajax({
url: "URL",
type: "POST",
data: {
eventId: $(e.target).attr('data-event-id'),
},
success: function(data) {
//Some code
},
error: function(data) {
//Some code
},
});
});
I include this script using "BookAsset".
Here
url: "URL",
I need URL to the action "book-event" in the controller Book.
On the server, I can do this:
Url::to('/book/book-event')
But how do I get URL on client side?
There is an solution:
1. js file include via BookAsset.
2. in view file I register bundle:
\frontend\assets\BookAsset::register($this);
3. in view file define a bookEventURL variable. Now it is available in the js-file.
$this->registerJs('var bookEventURL = ' . Url::to('/book/book-event') . ';');
But I do not like this solution.
What will happen when I use this script in many views. I have to define a variable bookEventURL in each view?
My Question. Is it possible to bind js-variables to my BookAsset. When I register my BookAsset in the view, in page source code automatically insert next code:
<script>var bookEventURL = "http://example.com/book-event/";</script>
A proper way of doing this is to add the needed information in your button tag, e.g. :
<?= Button::widget([
'label' => 'Order',
'options' => [
'class' => 'order-event-btn',
'data' => [
'url' => Url::to(['book/book-event']),
],
],
]) ?>
And in your js code :
$(".order-event-btn").click(function(e) {
var url = $(this).data('url');
// ...
});
But if you really want to "bind js-variables" to your BookAsset, you could simply override register() :
public static function register($view)
{
parent::register($view);
$view->registerJs('var bookEventURL = ' . json_encode(Url::to(['book/book-event'])) . ';');
}
If you wanna use it in different places of your application than I guess you should place it in the layout.

Categories

Resources