How to use "Fetch API" to pass data between javascript and c#? - javascript

I know about how to pass data between javascript and c# by ajax, and now I want to know fetch.
c#:
namespace WebApplication1
{
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
//[System.Web.Script.Services.ScriptService]
public class WebService1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
}
}
javascript:
fetch('http://localhost:62177/WebService1.asmx/HelloWorld')
.then(response => {
alert(response.json());
})
.then(response => {
alert(response);
})
it showed:
The usage of this url is based on ajax.
I changed the url to "http://localhost:62177/WebService1.asmx?op=HelloWorld", it showed:
I thought it was response success, however I received nothing and it showed:
Then I modified the method of return data, now it was json-format :
c#:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public void HelloWorld()
{
object JSONObj = JsonConvert.SerializeObject("Hello World");
Context.Response.Write(JSONObj);
}
But there was no change.
I don't know how else to change it. Can someone give me a little help?

The output of your web service doesn't produce JSON. It outputs "Hello World" when it should say something like:
{"YourKeyHere":"Hello World"}
I'd change the web service code to something like this:
[WebMethod]
[System.Web.Script.Services.ScriptMethod(UseHttpGet = true, ResponseFormat System.Web.Script.Services.ResponseFormat.Json)]
public void HelloWorld()
{
var obj = new { YourKeyHere = "Hello World" };
string JSONObj = JsonConvert.SerializeObject(obj);
Context.Response.Write(JSONObj);
}
At the top of your web service, uncomment this decoration: [System.Web.Script.Services.ScriptService]. It needs to be uncommented so that JavaScript (and maybe other clients) can see your service.
In your JavaScript, your response will come back as text (not json), and it will come with a {"d":null} bracket appended to it. To clean this up, I used substrings and placed them in a different function:
function SayHello()
{
//...
var options = {
method: 'GET' ,
headers: {
'Content-Type': 'application/json',
}
};
fetch("http://localhost:62177/WebService1.asmx/HelloWorld", options)
// Handle success
.then(response => response.text())
.then(result => DisplayResponse(result))
.catch(err => console.log('Request Failed', err));
//...
}
function DisplayResponse(result) {
console.log(result); //not sure why 'd:null' shows in output
console.log(result.substring(0, result.indexOf('{"d":null}'))); //get rid of 'd:null'
console.log(JSON.parse(result.substring(0, result.indexOf('{"d":null}')))); //get rid of 'd:null' then parse
}

You first need to make sure that your server is returning something in JSON format. But in addition, in your JS, you have to return the response.json() (or the response.text() or whatever method is appropriate) infetch` so that the stream can be processed, so that you can get a response in the next function:
fetch('http://localhost:62177/WebService1.asmx/HelloWorld')
.then(response => {
return response.json();
})
.then(responseJSON => {
alert(responseJSON);
})
The initial response is a response stream object, which doesn't actually contain any data yet.

Related

Is it able to read javascript file object in phython?

There is a client sending a file object in JavaScript.
There is a server written in Python.
Please have a look following code of both client and server.
Client(JavaScript):
function sendFile(file) {
fetch('http://localhost:8088', {
method: 'POST',
body: JSON.stringify({
name: "file",
code: file
})
})
.then(res => {
// handle response
var reader = res.body.getReader();
reader.read()
.then(({done, value}) => {
// need to check done
let chunks = new Uint8Array(value.length);
chunks.set(value, 0);
let result = new TextDecoder("utf-8").decode(chunks);
console.log(result);
});
})
.catch(err => {
// handle error
console.log('fetch error:', err);
});
}
document.getElementById('sendBtn').addEventListener('change',
()=>{this.sendFile(document.getElementById('fileInput').files[0]);});
Server(Python):
#!/usr/bin/python
import BaseHTTPServer
import json
class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
length = int(self.headers.getheader('content-length'))
body = self.rfile.read(length)
self.send_response(200)
self.send_header('Access-Control-Allow-Origin', '*')
self.end_headers()
self.wfile.write("post response")
data = json.loads(body)
# print data['file'] just returns '{ }'
# I would like to save this file on sever side.
# Is it possible??
server = BaseHTTPServer.HTTPServer(("localhost", 8088), MyHandler)
server.serve_forever()
I would like to want to know if there is a way to read file object written in javascript on python world.
I had to send file content How can I serialize an input File object to JSON?
And it is able to read and save it using dcodestring
How to parse data-uri in python?
Thank you all.

Passing parameter from Javascript to API in Controller

I was having some problem when trying to pass a parameter from jsp to controller. Here is the JavaScript where I call the API in Controller:
function help(value){
// need to pass the "value" parameter to this following API
window.open("<c:url value='doWavierGuide.do'/>", 'info', 'width=640,height=480,resizable=yes,scrollbars=yes')
}
And my controller as such:
#RequestMapping(value = "/doWavierGuide.do", method = RequestMethod.GET)
public ModelAndView showWavierGuide() {
Map<String, Object> modelMap = new HashMap<>();
log.debug("showWavierGuide() : Method is ");
// need to put the value passed in from javascript into here, temporary hardcoded
modelMap.put("method", "1");
return new ModelAndView("wavierGuide", modelMap);
}
But I not sure how can I pass the value from JavaScript to Controller. If I hardcoded the parameter value in Controller, the page managed to display. Any ideas? Thanks!
I managed to solve it by changing the url in jstl tag like this:
"<c:url value='doWavierGuide.do?method='/>"+value
And in the controller, retrieve the parameter using HttpServletRequest:
#RequestMapping(value = "/doWavierGuide.do", method = RequestMethod.GET)
public ModelAndView showWavierGuide(HttpServletRequest request) {
Map<String, Object> modelMap = new HashMap<>();
modelMap.put("method", request.getParameter("method"));
return new ModelAndView("wavierGuide", modelMap);
}
You have to use a library to make http requests to the server, or use fetch to send and receive data.
I leave an example:
const cnn = async (path, options) => {
const url = "www.example.com";
let result = await fetch(`${url}${path}`,
options
);
if (result.status >= 200 && result.status <= 299) {
return await result.json();
}
return { data: null, error: true }
}
// request to the API
cnn("doWavierGuide.do", { method: "GET", body: {name: "you_name"} })
.then(response => response.json())
.then(response => console.log(response))

Why PUT request with FormData object appends not sent to Laravel controller?

Why I can't sent FormData object values to my Laravel application
Javascript code:
console.log("Sending start...")
for (var value of company.values()) {
console.log(value);
}
this.$axios.put(url, company)
.then(res => {
console.log(res)
})
.catch(error => {
console.log(error)
})
Response preview:
Laravel controller:
public function update(Request $request, Company $company)
{
return response()->json($request->all());
}
Where I've any error?
Try to trick the Laravel framework by sending a POST request with axios assigning method type as PUT to FormData object.
Code:
// Lets create FormData object
let data = new FormData()
data.append('_method', 'PUT')
// ...........................
// other your appends here...
// Axios request
this.$axios.post(url, data)
.then(res => {
console.log(res)
})
After checking, let me know about the result of the code :)

Pending promise state using javascript fetch api with java spark (POST request)

I am trying to use ES6's fetch api to post some login data to a java spark server. The GET requests work perfectly, but when I try to POST something, the Promise on the client side stays 'pending'. I checked, and the server receives the request body, and parses it to an object. Using postman, it also returns true or false, so I think something is wrong with the CORS setup. I'm new to that, so i jut let * through, thinking it should work. I am using VueJS, but i don't think that really matters here, thought I'd add this info, maybe it helps. I will post the code below.
JS:
methods: {
login: function () {
data = '"perfectly valid json string"'
this.postData('http://te.st/login', data)
},
postData: function(url, data){
return fetch(url, {
body: data,
method: 'POST',
})
.then(response => response.json())
.then(function (result){
app.response = result
})
}
}
Java:
private static void enableCORS(final String origin, final String methods, final String headers) {
options("/*", (request, response) -> {
String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers");
if (accessControlRequestHeaders != null) {
response.header("Access-Control-Allow-Headers", accessControlRequestHeaders);
}
String accessControlRequestMethod = request.headers("Access-Control-Request-Method");
if (accessControlRequestMethod != null) {
response.header("Access-Control-Allow-Methods", accessControlRequestMethod);
}
return "OK";
});
before((request, response) -> {
response.header("Access-Control-Allow-Origin", origin);
response.header("Access-Control-Request-Method", methods);
response.header("Access-Control-Allow-Headers", headers);
response.type("application/json");
});
}
(called in the code as enableCORS("*","GET,POST","Origin, Content-Type, Access-Control-Allow-Origin"); )
And the endpoint:
post("/login", (req, res) -> {
boolean ret = dao.checkLogin(gson.fromJson(req.body(), User.class));
return gson.toJson(ret);
});

React-Native modules for Android int value returned late?

I have a native Android app that now has a React-Native part to it.
In short, i have a list view in native Android/Java. When i tap a row, i start a new Activity which leads to the React-Native code.
The components make an API call, but before it does it, my code goes through the React Native module to get a value from the User Preferences in the Java/Android settings for the header so that it can make the proper API call.
The React Native API call in /actions/index.js:
export const toggleBlocked = (user_id) =>
async dispatch => {
try {
let headers = await getHeaders();
const response = await fetch('http://my.domain.com/api/get_data?user_id=`${user_id}`', { headers, method: 'GET' });
if (response.status == 200) {
// do stuff
} else {
ToastAndroid.show("Looks like the response wasnt good :(", ToastAndroid.LONG, ToastAndroid.CENTER);
}
} catch (error) {
ToastAndroid.show("An Error Occurred :(", ToastAndroid.LONG, ToastAndroid.CENTER);
}
};
function getHeaders() {
let userId = UserService.getUserId()
console.log("2. React-Native | getHeaders... user_id is " + userId)
return (
new Headers({
Cookie: `abcxyz=${userId}`,
user_id: userId,
"User-Agent": "android",
"Content-Type": "application/json",
charset: "utf-8",
"app-version": "9.1.23",
Accept: "application/json"
})
)
}
Back in native Android/Java, i have my modules and packages set up. Here is UserServiceModule.java:
#ReactMethod
public int getUserId() {
SharedPreferences settings = mContext.getSharedPreferences(Constants.SettingsPreference, Context.MODE_PRIVATE);
int userId = settings.getUserId();
Log.d(TAG, "1. Java/Android code. UserID is " + userId);
return userId;
}
When i run the code, user_id is always null. I even expected my logs to show in order (see the numbered logs), but they're reverse??
"1. Java/Android code. UserID is 123"
"2. React-Native | getHeaders... user_id is 123"
Any insights would be great please. Thanks.
UPDATE / SOLUTION
Here is the updated changes to get things working correctly:
#ReactMethod
public void getUserId(final Promise promise) {
SharedPreferences settings = mContext.getSharedPreferences(Constants.SettingsPreference, Context.MODE_PRIVATE);
int userId = settings.getUserId();
Log.d(TAG, "1. Java/Android code. UserID is " + userId);
promise.resolve(Integer.toString(userId));
}
#ReactMethod functions are always suppose to return void and are asynchronous. The reason you are getting null is because your JS code is written synchronously. It initializes the variable userId as null and sets it with the return value of the asynchronous call. But because the code you written was synchronous, it will go to the next line before the react method comes back with the value.
You will need to do an async await like you did with your dispatch method. However that won't be enough as react methods return a void value. Quite frankly I don't know how a method not found error was not triggered instead. Perhaps #ReactMethod ignores the return value you defined in Java?
Regardless, after setting up the async await. Do something similar to what they did here:
https://facebook.github.io/react-native/docs/native-modules-android.html#callbacks
Set isBlockingSynchronousMethod = true in #ReactMethod
example:
#ReactMethod(isBlockingSynchronousMethod = true)
public String getString(){
return "awesome string";
}
in js file:
var someString = await NativeModule.ModuleName.getString();

Categories

Resources