unable to perform CRUD in JSON-SERVER - javascript

I am trying to add, update, delete in JSON server with Redux Axios. But I am unable to perform CRUD action. I am always getting an error 404. I am using the following code example. this my db.json
{
"orderdetails": [
{
"OrderID": 111,
"CustomerID": "VINET",
}
]
}
I am using the following code for importing Axios from redux. Please find my server.js
import axios from 'axios';
export default axios.create({
baseURL: "http://localhost:3007/",
headers: {
"Content-type": "application/json"
}
})
I am using the following code example for performing CRUD action in the JSON-Sever. But, I am got a error
import http from "../serverapi";
create(data) {
return http.post("/orderdetails/posts", data);
}
update(id, data) {
return http.put(`/orderdetails/${id}`, data);
}
delete(id) {
return http.delete(`/orderdetails/${id}`);
}
could you please provide the suggestion?

If you are using the json-server npm package, there are a couple of problems with your usage.
First, you db.json is invalid. It should be somewhat like this:
{
"orderdetails": [
{
"OrderID": 111,
"CustomerID": "VINET"
},
{
"OrderID": 12,
"CustomerID": "VINET"
}
]
}
Make sure to check the API url in the browser first.
Second, json-server by default runs on localhost:3000 (Not sure if it can be changed, check the docs here https://www.npmjs.com/package/json-server). Your API is pointing to port 3007 as seen here baseURL: "http://localhost:3007/,
Lastly, you cannot do a request like http://localhost:3000/orderdetails/111. The last part in the api url by default corresponds to the id key in db.json, but since your key is OrderID, your API end point should be modified to http://localhost:3000/orderdetails?OrderID=111. Try this url in your browser, it should return the correct object.
UPDATE
Update operations in json-server require the id key to be present in the db.json file. Hence, update your db.json as follows:
{
"orderdetails": [
{
"id": 1,
"OrderID": 111,
"CustomerID": "VINET"
},
{
"id": 2,
"OrderID": 12,
"CustomerID": "VINET"
}
]
}
Then, you can try running a POST request on the url http://localhost:3000/orderdetails and json body :
{
"OrderID": 12333,
"CustomerID": "VINET"
}
This will create a new object in the db, with incremented id. PUT, DELETE requests can be made using the id param in the url like http://localhost:3000/orderdetails/3.

Related

data Provider using simpleRestProvider "The response to 'getList' must be like"

I am trying to get some data from a json-server feeded to an express server but I am getting an this error: The response to 'getList' must be like { data : [...] }, but the received data is not an array. The dataProvider is probably wrong for 'getList' ra.notification.data_provider_error at validateResponseFormat (validateResponseFormat.ts:30:1) at useDataProvider.ts:109:1
Json server and the headers:
server.use(cors());
const allowCrossDomain = (req, res, next) => {
res.header("Access-Control-Expose-Headers", "Content-Range");
res.header("Content-Range", "cakeData 0:20/*");
next();
};
server.use(allowCrossDomain);
server.use("/api", jsonServer.router("api/db.json"));
The db.json
{
"cakeData": [
{
"id": 1,
"imageurl": "https://images.unsplash.com/photo-1674991773078-12a3eab409b2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=627&q=80",
"name": "cake",
"description": "information about cake"
},
{
"id": 2,
"imageurl": "https://images.unsplash.com/photo-1674991773078-12a3eab409b2?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=627&q=80",
"name": "cake",
"description": "information about cake"
}
]
}
And the react admin component:
<Admin
basename="/admin"
dataProvider={simpleRestProvider("http://localhost:3000/")}
>
<Resource
name="cakeData"
list={ProductList}
create={CreateProduct}
edit={EditProduct}
/>
</Admin>
What am I missing? using only json-server with middlewares was working but as I feed the json-server to express I get the error mentioned above.
As a sidenote I am using proxy in react to proxy from port 3000 to 5000
found the answer. Express was returning an html and the api call was wrong.

Getting parameters from an Azure Function to use in function.json bindings

I am new to Azure Functions and I'm having trouble with some of the basics, in particular how to pass parameter data to function.json so that I can write a blob to Azure Blob Storage using the Storage Connector.
My question is, how do I specify a parameter within the httpTrigger function that can be used by the outputBlobContents binding below?
My setup is pretty simple (but doesn't work yet):
function.json:
{
"bindings": [
{
"authLevel": "function",
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "blob",
"direction": "out",
"name": "outputBlobContents",
"path": "uploaded_files/{destinationFilename}",
"connection": "MY_STORAGE"
}
]
}
index.ts:
import { AzureFunction, Context, HttpRequest } from "#azure/functions"
const httpTrigger: AzureFunction = async function (context: Context, req: HttpRequest): Promise<void> {
context.bindingData.destinationFilename = "testfile.pdf";
context.bindings.outputBlobContents = context.req.body;
const responseMessage = "uploaded file";
context.res = {
status: 201,
body: responseMessage
};
};
export default httpTrigger;
In my example code I am trying assign destinationFilename to the context.bindingData object, but this does not work. I've read through all the documentation but it's not very clear about what the bindingData object actually is or how named parameters work in general. How do I tell the blob storage connector where to store the file?
Simply put, any form of json input will be obtained as a parameter. Inside the function is impossible. If you want to use it inside the function, please choose to directly use the sdk of Azure Storage.
Since you use httptrigger, you can send a request body in json format, like this:
{
"destinationFilename":"something"
}
After that, output binding can get the value.

How to get JSON payload sent by the Slack action message?

I am trying to build a Slack bot with interactive buttons. I have set up a Google Apps Script to handle the action performed on the Slack message. I want the payload of the request sent by the Slack. I have tried to get the request object by doing
function doPost(e) {
return processComment(e);
}
function processComment(e) {
Logger.log(e);
}
{postData=FileUpload, queryString=method=slack, parameter={method=slack, payload={"type":"block_actions","user":{"id":"U01835Mxxxx","username":"ravsamteam","name":"ravsamteam","team_id":"T0160UQZZZZ"},"api_app_id":"A018MPZ2xxx","token":"NTNRCTPDz8mxxxzxxxxxxxxx","container":{"channel_id":"C0190D8L2AU","is_ephemeral":false,"message_ts":"1597154895.001500","type":"message"},"trigger_id":"1281039280903.1204976558018.aa1055f6900d7884d9cd4ac34ffzzzzz","team":{"id":"T0160UQGE0J","domain":"ravsamhq"},"channel":{"id":"C0190D8L2AU","name":"blogs"},"message":{"type":"message","subtype":"bot_message","text":"This content can't be displayed.","ts":"1597154895.001500","bot_id":"B019BNL08BS","blocks":[{"type":"section","block_id":"mNavk","text":{"type":"mrkdwn","text":" New comment on RavSam's blog by hello","verbatim":false}},{"type":"section","block_id":"v3Ip","text":{"type":"mrkdwn","text":"*Blog:*\nhello\n\n*Comment:*\nravgeet errorCannot read property 'payload' of undefined","verbatim":false}},{"type":"actions","block_id":"1maVO","elements":[{"type":"button","action_id":"WSo=","text":{"type":"plain_text","text":"Approve","emoji":true},"style":"primary","value":"approved"},{"type":"button","action_id":"Vek\/","text":{"type":"plain_text","text":"Deny","emoji":true},"style":"danger","value":"denied"}]}]},"response_url":"https:\/\/hooks.slack.com\/actions\/T0160Uxxxxx\/1301968xxxxxx\/Q3gZhbeUCUIxxxxxxxxxxxxx","actions":[{"action_id":"WSo=","block_id":"1maVO","text":{"type":"plain_text","text":"Approve","emoji":true},"type":"button","value":"approved","action_ts":"1597213837.152704"}]}}, contentLength=2391.0, parameters={payload=[Ljava.lang.Object;#53f2e9fa, method=[Ljava.lang.Object;#5793298b}, contextPath=}
How do I get the payload? Once I have the payload JSON, I can use the actions to determine what action was taken by the user?
Yes. The payload contains all the information you need to identify the action. And it also contains a response_url to respond back.
Slack payload should look like this.
{
"actions": [
{
"name": "channels_list",
"selected_options": [
{
"value": "C012AB3CD"
}
]
}
],
"callback_id": "select_simple_1234",
"team": {
"id": "T012AB0A1",
"domain": "pocket-calculator"
},
"channel": {
"id": "C012AB3CD",
"name": "general"
},
"user": {
"id": "U012A1BCD",
"name": "musik"
},
"action_ts": "1481579588.685999",
"message_ts": "1481579582.000003",
"attachment_id": "1",
"token": "iUeRJkkRC9RMMvSRTd8gdq2m",
"response_url": "https://hooks.slack.com/actions/T012AB0A1/123456789/JpmK0yzoZDeRiqfeduTBYXWQ",
"trigger_id": "13345224609.738474920.8088930838d88f008e0"
}
You can learn more here.

how to check if database needs auth or not

I'm working on a project which allows user to login to a mongodb database. Basically I have
db.authenticate(username, password, function(err, isAuthPass) {...}
to check if the user pass the authentication. However, sometimes the server doesn't need authentication. If I provide username/password, it will fail. So I need to know how to check auth mode with mongo-native-client. Any idea?
Well I suppose you could just interrogate the database for the config information. This does come with the caveat that you should also be using the "test/fail" methods as discussed before as you would not be able to get this information from a server with authentication enabled that is not running on localhost:
var mongo = require('mongodb'),
MongoClient = mongo.MongoClient;
MongoClient.connect('mongodb://localhost:30000/test',function(err,db) {
var adminDb = db.admin();
adminDb.command({ "getCmdLineOpts": 1 },function(err,result) {
console.log( JSON.stringify( result, undefined, 4 ) );
});
});
That shows the "parsed" options, and it does not matter whether they are actually sent from the command line or picked up from a config file as the output here suggests:
{
"documents": [
{
"argv": [
"mongod",
"--config",
"mongod.conf"
],
"parsed": {
"config": "mongod.conf",
"net": {
"bindIp": "0.0.0.0",
"port": 30000
},
"security": {
"authorization": "enabled"
},
"storage": {
"dbPath": "data"
},
"systemLog": {
"destination": "file",
"logAppend": true,
"path": "log/mongod.log"
}
},
"ok": 1
}
],
"index": 338,
"messageLength": 338,
"requestId": 25,
"responseTo": 3,
"responseFlag": 8,
"cursorId": "0",
"startingFrom": 0,
"numberReturned": 1
}
So here the presence of "security.authorization.enabled": true tells you that further operations are going to require authorized credentials to be supplied.
Also see getCmdLineOpts and other diagnostic information commands that should be useful for your tool.
Sometimes? always use a password. and if you don't need one, like your local environment, you should use a config file for that environment like ./config/dev.js which has the credentials for that environment.

AngularJS / Restangular routing "Cannot set property 'route' of undefined"

I have a AngularJS-based frontend using restangular to fetch records from a Django backend I've built.
I'm making a call for a client list with the following:
var app;
app = angular.module("myApp", ["restangular"]).config(function(RestangularProvider) {
RestangularProvider.setBaseUrl("http://172.16.91.149:8000/client/v1");
RestangularProvider.setResponseExtractor(function(response, operation) {
return response.objects;
});
return RestangularProvider.setRequestSuffix("/?callback=abc123");
});
angular.module("myApp").controller("MainCtrl", function($scope, Restangular) {
return $scope.client = Restangular.all("client").getList();
});
Chrome is showing the backend returning data with an HTTP 200:
abc123({
"meta": {
"limit": 20,
"next": "/client/v1/client/?callback=abc123&limit=20&offset=20",
"offset": 0,
"previous": null,
"total_count": 2
},
"objects": [{
"id": 1,
"name": "Test",
"resource_uri": "/client/v1/client/1/"
}, {
"id": 2,
"name": "Test 2",
"resource_uri": "/client/v1/client/2/"
}]
})
But once that happens I'm seeing the following stack trace appear in Chrome's console:
TypeError: Cannot set property 'route' of undefined
at restangularizeBase (http://172.16.91.149:9000/components/restangular/src/restangular.js:395:56)
at restangularizeCollection (http://172.16.91.149:9000/components/restangular/src/restangular.js:499:35)
at http://172.16.91.149:9000/components/restangular/src/restangular.js:556:44
at wrappedCallback (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6846:59)
at http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:6883:26
at Object.Scope.$eval (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8057:28)
at Object.Scope.$digest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:7922:25)
at Object.Scope.$apply (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:8143:24)
at done (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9170:20)
at completeRequest (http://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.js:9333:7) angular.js:5754
I did a breakpoint on line 395 in in restangular.js:
L394 function restangularizeBase(parent, elem, route) {
L395 elem[config.restangularFields.route] = route;
The first time it hits the breakpoint elem is just an object and route has the value of client.
The second time the breakpoint is hit elem is undefined and route has the value of client.
Any ideas why elem would be undefined the second time around?
When requesting lists, Restangular expects the data from the server to be a simple array. However, if the resulting data is wrapped with result metadata, such as pagination info, it falls apart.
If you are using Django REST Framework, it will return results wrapped like this:
{
"count": 2,
"next": null,
"previous": null,
"results": [
{
"id": 1,
"name": "Foo"
},
{
"id": 2,
"name": "Bar"
}
]
}
To translate this, you need to create a response extractor function. It's easiest to specify in the module config:
angular.module('myApp', ['myApp.controllers', 'restangular']).
config(function(RestangularProvider) {
RestangularProvider.setBaseUrl("/api");
// This function is used to map the JSON data to something Restangular
// expects
RestangularProvider.setResponseExtractor(function(response, operation, what, url) {
if (operation === "getList") {
// Use results as the return type, and save the result metadata
// in _resultmeta
var newResponse = response.results;
newResponse._resultmeta = {
"count": response.count,
"next": response.next,
"previous": response.previous
};
return newResponse;
}
return response;
});
});
This rearranges the results to be a simple array, with an additional property of _resultmeta, containing the metadata. Restangular will do it's thing with the array, and it's objects, and you can access the _resultmeta property when handling the array as you would expect.
I'm the creator of Restangular.
The restangularizeBase function is called first for your collection and then for each of your elements.
From the StackTrace, the element is OK, but once the collection is sent to restangularizeBase, it's actually undefined. Could you please console.log response.objects? Also, please update to the latest version.
Also, for the default request parameter, you should be using defaultRequestParams instead of the requestSuffix. requestSuffix should only be used for the ending "/"
Let me know if I can help you some more!

Categories

Resources