AngularJs Multipart $http Request Issue - javascript

For some reason I can't get [object Object] out of the form. I'm using hte method found here:
http://badwing.com/multipart-form-data-ajax-uploads-with-angularjs/#comment-431
The JSON i'm sending is pretty complicated (sample):
{
"challenge_id": 262,
"priority": "0",
"cause_id": "29",
"timestamp": "2013-11-29 12:06:01",
"translations": {
"en": {
"name": "asdfgsfd",
"description": "sdfghfs"
}
},
"actions": {
"1": {
"type": "chek",
"step": "1",
"translations": {
"en": {
"description": "adsfas"
}
}
},
"2": {
"type": "chek",
"step": "2",
"translations": {
"en": {
"description": "fsdgsd"
}
}
}
}
}
My response looks like this:
Content-Disposition: form-data; name="challenge_json"
[object Object]
My request looks like this:
return $http.post( REQUEST_URL + '/ENDPOINT', {challenge_json:data}, {
transformRequest: function(data) {
console.log(data);
var fd = new FormData();
angular.forEach(data, function(value, key) {
fd.append(key, value);
});
console.log(fd);
return fd;
}
Im modifying the headers with a httpProvider configuration change. But have tried doing it in line and am getting the same result.
any help would be appreciated.

It seems you were close to the solution, but needed to unset the 'content-type' header in the options passed to $http, so that the xmlhttprequest object can add it automatically when it gets a formdata on its send method.
https://groups.google.com/d/topic/angular/MBf8qvBpuVE/discussion
see a playground here http://jsfiddle.net/Lv1n55db/1/
(providing FormData object directly and a no-op transform, or your way of providing a normal data object and transforming it to FormData in transformRequest is no significant difference, the key is in the headers option)
headers:{'Content-Type':undefined},
It may vary with differnt browsers and different angularjs versions too.
A more certain and stable approach, at least if you do not need file fields and such, could be to not use native FormData but implement the serialization to string yourself, as FormData polyfills do it.

Related

Use variables in Azure Functions out binding

I'm using Azure functions with javascript, and i would like to modify the out binding of path in my functions. For example this is my function.json:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "outputBlob",
"path": "container/{variableCreatedInFunction}-{rand-guid}",
"connection": "storagename_STORAGE",
"direction": "out",
"type": "blob"
}
]
I Would like to set {variableCreatedInFunction} in index.js, for example:
module.exports = async function (context, req) {
const data = req.body
const date = new Date().toISOString().slice(0, 10)
const variableCreatedInFunction = `dir/path/${date}`
if (data) {
var responseMessage = `Good`
var statusCode = 200
context.bindings.outputBlob = data
} else {
var responseMessage = `Bad`
var statusCode = 500
}
context.res = {
status: statusCode,
body: responseMessage
};
}
Couldn't find any way to this, is it possible?
Bindings are resolved before the function executes. You can use {DateTime} as a binding expression. It will by default be yyyy-MM-ddTHH-mm-ssZ. You can use {DateTime:yyyy} as well (and other formatting patterns, as needed).
Imperative bindings (which is what you want to achieve) is only available in C# and other .NET languages, the docs says:
Binding at runtime In C# and other .NET languages, you can use an
imperative binding pattern, as opposed to the declarative bindings in
function.json and attributes. Imperative binding is useful when
binding parameters need to be computed at runtime rather than design
time. To learn more, see the C# developer reference or the C# script developer reference.
MS might've added it to JS as well by now, since I'm pretty sure I read that exact section more than a year ago, but I can't find anything related to it. Maybe you can do some digging yourself.
If your request content is JSON, the alternative is to include the path in the request, e.g.:
{
"mypath":"a-path",
"data":"yourdata"
}
You'd then be able to do declarative binding like this:
{
"name": "outputBlob",
"path": "container/{mypath}-{rand-guid}",
"connection": "storagename_STORAGE",
"direction": "out",
"type": "blob"
}
In case you need the name/path to your Blob, you'd probably have to chain two functions together, where one acts as the entry point and path generator, while the other is handling the Blob (and of course the binding).
It would go something like this:
Declare 1st function with HttpTrigger and Queue (output).
Have the 1st function create your "random" path containing {date}-{guid}.
Insert a message into the Queue output with the content {"mypath":"2020-10-15-3f3ecf20-1177-4da9-8802-c7ad9ada9a33", "data":"some-data"} (replacing the date and guid with your own generated values, of course...)
Declare 2nd function with QueueTrigger and your Blob-needs, still binding the Blob path as before, but without {rand-guid}, just {mypath}.
The mypath is now used both for the blob output (declarative) and you have the information available from the queue message.
It is not possiable to set dynamic variable in .js and let the binding know.
The value need to be given in advance, but this way may achieve your requirement:
index.js
module.exports = async function (context, req) {
context.bindings.outputBlob = "This is a test.";
context.done();
context.res = {
body: 'Success.'
};
}
function.json
{
"bindings": [
{
"authLevel": "anonymous",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"get",
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"name": "outputBlob",
"path": "test/{test}",
"connection": "str",
"direction": "out",
"type": "blob"
}
]
}
local.settings.json
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "node",
"str":"DefaultEndpointsProtocol=https;AccountName=0730bowmanwindow;AccountKey=xxxxxx;EndpointSuffix=core.windows.net"
}
}
Or you can just put the output logic in the body of function. Just use the javascript sdk.

pass json in process variables in camunda process

I am trying to pass json payload in variables as value to start a process definition using engine-rest api as below:-
API:
http://localhost:8080/engine-rest/process-definition/processService:1:9459dbe9-6b2c-11e8-b9e8-28d2447c697a/start
Body :
{
"variables": {
"payload": {
"value": {
"mode": "email",
"meta": [{
"key": "topic",
"value": "weather"
}, {
"key": "qos",
"value": "2"
}]
},
"type": "Json"
}
}
}
but it is giving 400 BAD REQUEST with below error:-
Must provide 'null' or String value for value of SerializableValue type 'Json'.
Also i have used a expression in my BPMN process to fetch a key-value pair like below, it also throwing me error :-
${S(payload).prop("mode").stringValue() == 'email'}
Now working steps:-
when i try to send body json payload in string format then it works fine.
API:
http://localhost:8080/engine-rest/process-definition/processService:1:9459dbe9-6b2c-11e8-b9e8-28d2447c697a/start
Body:
{
"variables": {
"payload": {
"value": "{\"mode\": \"email\",\"meta\": [{\"key\": \"topic\",\"value\": \"weather\"},{\"key\": \"qos\",\"value\": \"2\"}]}",
"type": "String"
}
}
}
same java code i am using here to fetch json payload-
public void notify(DelegateExecution delegateProcessExecution) throws Exception {
Object notificationPayload =
delegateProcessExecution.getVariable("payload");
if (null != notificationPayload) {
String notifyPayload = notificationPayload.toString();
JSONObject inputJson = new JSONObject(notifyPayload);
}
// ...
}
So i want this payload as json for whole process so that i don't need to convert it to string as above working example.
You should only change the type to "json", example:
{
"variables": {
"broker": {
"value": "{\"name\":\"Broker Name\"}",
"type": "json"
}
}
}
This is by design in the rest engine API, they support other data formats, too, so it has to be an escaped JSON String, see https://app.camunda.com/jira/browse/CAM-9617.
The solution is to pass an escaped JSON String as value, as you have pointed out above. One can also use "type": "Object" if the engine has a Jackson Java Bean on the classpath that matches the given value. You supply the bean type name in a valueInfo object:
https://docs.camunda.org/manual/7.10/reference/rest/process-definition/post-start-process-instance/#request-body
For example:
{
"variables": {
"payload": {
"value": "{\"mode\": \"email\",\"meta\": [{\"key\": \"topic\",\"value\": \"weather\"},{\"key\": \"qos\",\"value\": \"2\"}]}",
"type": "String",
"valueInfo": {
"objectTypeName": "my.own.BeanWithModeAndMetaProps",
"serializationDataFormat": "application/json"
}
}
}
}

How can I post a container in Storage api from loopback?

I already have declared my datasource ,my model and the connector between these.
My model
{
"name": "container",
"base": "Model",
"idInjection": true,
"options": {
"validateUpsert": true
},
"properties": {},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}
Datasource
"storage": {
"name": "storage",
"connector": "loopback-component-storage",
"provider": "filesystem",
"root": "./server/storage"
}
My provider
{
"filesystem": {
"root": "./server/storage"
}
}
And the Connector
"container": {
"dataSource": "storage",
"public": true
}
I try posting a object like {"Object":"container1"} into path "./server/storage" but I get the following error from callback.
{
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Path must be a string. Received undefined",
"stack": "TypeError: Path must be a string. Received undefined.."
}
}
Please who can help me to find my issue? Thanks!
You can also use "name" instead of "Object" as key in your JSON object to create a new container/directory using the API.
POST /api/containers {"name":"container1"}
The way to post a container is, without using the loopback api. Create a folder that is gonna be the container into your provider path (being filesystem).
As simple as that!
If you need a programmatic way to add new containers, let's say for example you want to create a filesystem of sorts for new users. You can use the route below. "Container" is the name I called my Model, you can call yours whatever you'd like.
POST localhost:3000/api/container
Inside the body of the post request you have to have an attribute name and the value of the name can be the new container you're creating. The Strongloop/Loopback documentation, which can be found here, is not accurate and neither is the error you get back when you try to post it with their directions.
"error": {
"statusCode": 500,
"name": "TypeError",
"message": "Path must be a string. Received undefined"
}
An excerpt of the code to send a post request to create a new container is also below.
var request = require("request");
var options = {
method: 'POST',
url: 'http://localhost:3000/api/containers',
body: { name: 'someNewContainer' },
json: true
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log(body);
});

Syntax for JSON 'payload' in Facebook FB.api post

I'm trying to add users to a Custom Audience in Facebook, and I believe I have bungled the payload piece of the request below.
The error returned is:
(#100) Missing required parameter: payload
For reference, I'm generating the hash using Crypto-JS. Here's the code I tried:
var payload = { "payload": [{ "schema": "EMAIL_SHA256", "data": [hash] }]};
FB.api('/000000000/users', 'post', payload, function (response) {
if (response && !response.error) {
alert("This worked");
} else {
alert(response.error.message);
}});
The FB.api documentation shows that it expects 'payload' as a JSON object (https://developers.facebook.com/docs/marketing-api/custom-audience-targeting/v2.3#add). I just haven't been able to figure out the correct syntax yet. The example in the Facebook API documentation shows the following:
payload = {"schema":"EMAIL_SHA256","data":["HASH", "HASH", "HASH" ]}
Here's what I have so far (not working):
var payload = { "payload": [{ "schema": "EMAIL_SHA256", "data": [hash] }]};
Can anyone assist with the syntax? I've found plenty of examples of JSON objects and arrays, but I haven't seen anything that matches this format:
payload = {"schema":"EMAIL_SHA256","data":["HASH", "HASH", "HASH" ]}
For the benefit of any other JS/JSON novices, I finally figured it out after more experimentation:
var payload = { "payload": { "schema": "EMAIL_SHA256", "data": [hash] } };

The confuse about use jquery $.ajax to read javascript file

suppose I have a config javascript file:
window.Config = {};
Config.UI = {
"Area": {},
"Layer": {},
"Sprites": {},
"Audio": {}
};
Config.UI.Area = {
"prop": {
"uuid": {
"_type": "string",
},
"frame": {
"_type": "rect",
"_value": {
"x": "0",
},
"_aka": "frame"
},
"zIndex": {
"_type": "string",
}
},
then I want use $.ajax to read this file:
$.ajax({
url:'js/config.js',
success:function (data, textStatus) {
console.log(data);
}
})
the question is how can I get some key's value in the config,by use the data $.ajax return?
like the "Config.UI" or the 'uuid' in ui.area.prop?Or can I convert them to json?
Rather than use AJAX, why not just insert a script?
var script = $('<script>');
script.attr('type', 'text/javascript');
script.attr('src', 'js/config.js');
script.bind('load', function() {
// use window.Config
});
script.appendTo('head');
icktoofay has a good suggestion, and the issue with the jQuery.ajax call looks to be a missing dataType: 'script' option which will evaluate the response and should give you object access. You might want to look into jQuery.getscript() as well.
I find it very useful and powerful to store data on the server as javascript objects and read them using Ajax. And it is very easy to do. Let me give you an example from an educational application I have written.
This is an example table of contents file (l1contents.js) that I would store on the server:
{
title : "Lesson 1",
topics : [
{name : "Topic 1", file : "l1t1data.js" },
{name : "Topic 2", file : "l1t2data.js" },
]
}
This is the javascript code I use to process the file:
$.ajax({
url : contentsFileName, // would be set to 'l1contents.js'
dataType : 'text', // yes this is correct, I want jquery to think this is text
cache : false,
success: function(data) {
var contentsObj = eval('(' + data + ')');
var lessonTitle = contentsObj.title;
for (var i = 0; i < contentsObj.topics.length; i++) {
var topic = contentsObj.topics [i];
// process topic.name and topic.file here
}
}
});
Obviously, this is simplified, but hopefully you get the idea. I simply use eval to set the object. And note that I don't even need any javascript code defining the structure of contentsObj. (I, of course, do have extensive comments defining the structure of my objects, but they are simply comments, not code.)
if your json file contains json data than you can use parseJSON() , toJSON() method.
and another solution is use eval(), this conver json data to javascript object so you can easly get a value by giving key.

Categories