I'm trying to create a public gist via javascript. I'm not using any authentication - this is all client-side.
var gist = {
"description": "test",
"public": true,
"files": {
"test.txt": {
"content": "contents"
}
}
};
$.post('https://api.github.com/gists', gist, function(data) {
});
The above code throws a 400: Bad Request - Problems parsing JSON. However, my JSON is valid. Any ideas?
Aha - I can't pass an object to $.post. It needs to be stringified first:
var gist = {
"description": "test",
"public": true,
"files": {
"test.txt": {
"content": "contents"
}
}
};
$.post('https://api.github.com/gists', JSON.stringify(gist), function(data) {});
Related
How can I select multiple fields when using the documents.get ?
Right now I am getting the documenmt like this:
const doc = await docs.documents.get({
documentId: copiedFile.data.id,
fields: 'body/content'
});
which returns this:
"data": {
"body": {
"content": [...]
}
}
However, I need to also get the inlineObject and the only way so far I have been able to do so, is by removing the fields proeprty completely
const doc = await docs.documents.get({
documentId: copiedFile.data.id,
});
Then I get this:
"data": {
"title": "Some document title",
"body": {
"content": [...]
},
"headers": {
},
"footers": {
},
"documentStyle": {
},
"namedStyles": {
},
"lists": {
},
"revisionId": "some-long-id",
"suggestionsViewMode": "SUGGESTIONS_INLINE",
"inlineObjects": {
},
"documentId": "some-long-id"
}
But I am really only interested in data.body.content and data.inlineObjects
When selecting everything the response is many thousands of lines of json larger, which I don't want.
I have tried fields: ['body/content', 'inlineObjects'] but that only returns body.content and not the inlineObjects - also the documentation doesn't mention this syntax anywhere, it was just to experiment.
I think it doesn't return any inlineObjects when you don't have any inlineObjects in the document. To confirm if the actual format is working and the statement above is true, try using other fields where a value is confirmed to be returned such as revisionId or title.
Test:
const doc = await docs.documents.get({
documentId: copiedFile.data.id,
fields: 'body/content,inlineObjects'
});
Output:
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.
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);
});
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.
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.