in Vue PUT POST DELETE method showing not allowed when middlewear included - javascript

I am trying to implepement vue in my laravel application. Simple CRUD. The fetching and showing of data is working fine, but edit, delete, add is not. It is working if there is no auth checking middlewear in feedController. Need to make it work while the middlewear included.
Here is my add method:
fetch('api/feed', {
method: 'post',
body: JSON.stringify(this.feed),
headers: {
'content-type': 'application/json'
}
})
.then(res => res.json())
.then( data=> {
this.feed.title = '';
this.feed.body = '';
alert('Feed Added');
this.fetchFeeds();
})
Here is my delete method:
deleteFeed(id){
if (confirm('Are you sure you want to delete?')){
fetch(`api/feed/${id}`, {
method: 'delete'
})
.then(res => res.json())
.then(data=> {
alert('Article Removed');
this.fetchFeeds();
})
.catch(err => console.log(err));
}
}
Here are the routes in api.php
/Create new feed
Route::post('feed', 'FeedController#store');
//Update feed
Route::put('feed', 'FeedController#store');
//Delete feed
Route::delete('feed/{id}', 'FeedController#destroy');
And finally here is the controller's functions where the middlewear is.
For adding:
public function store(Request $request)
{
$feed = $request->isMethod('put')?Feeds::findOrFail($request->feed_id):new Feeds;
$feed->id= $request->input('feed_id');
$feed->title= $request->input('title');
$feed->body= $request->input('body');
// $feed->image= "Test Image String";
// $feed->link="Test Link String";
// $feed->user_id=4;
if($feed->save())
{
return new FeedResource($feed);
}
}
For deleting:
public function destroy($id)
{
$feed = Feeds::findOrFail($id);
if ($feed->delete()){
return new FeedResource($feed);
}
}

Related

AJAX Javscript - PHP

I learn MVC and make some AJAX interaction. So I've routes file with
'cart/addProductAjax' => 'cart/addProductAjax',
CartController with actionAddProductAjax:
<?php
class CartController
{
public function actionIndex() {
}
public function actionAdd($productId) {
Cart::addProduct($productId);
$referer = '/';
if (isset($_SERVER['HTTP_REFERER'])) {
$referer = $_SERVER['HTTP_REFERER'];
}
header("Location: $referer");
}
public function actionAddProductAjax() {
$productId = $_POST['productId'];
print_r($_POST);
exit;
Cart::addProduct($productId);
$itemsAmount = Cart::countItems();
exit(json_encode($itemsAmount));
}
}
And JS piece of code that send request and receive response from the server:
document.body.addEventListener('click', event => {
if(event.target.classList.contains('add-to-cart')) {
event.preventDefault();
let productId = event.target.dataset.id;
let response = fetch("/cart/addProductAjax/", {
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=utf-8'
},
body: JSON.stringify(productId),
})
.then(response => response.json())
.then(response => console.log(response));
}
});
And nothing works. I think there is an error somewhere in PHP method. What shoul I do to make it work?

Controller method won't got parameters

I made a post ajax request to server side.
the request reached to the server but the recieved parameters are empty/null.
no idea why this is happening, the problem is probably in the server. tried many solutions but nothing changed.
I hope some of you can help me.
fetch('Home/AddMovie', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
movie: data_object
}),
}).then(res => res.text())
.then(text => {
})
.catch((error) => {
console.error('Error:', error);
});
[HttpPost]
public void AddMovie(Movie movie)
{
var movies = new List<Movie>();
var newJson = "";
using (StreamReader r = new StreamReader(JsonFilePath))
{
string json = r.ReadToEnd();
movies = JsonConvert.DeserializeObject<List<Movie>>(json);
movies.Add(movie);
newJson = JsonConvert.SerializeObject(movies, Formatting.Indented);
}
System.IO.File.WriteAllText(JsonFilePath, newJson);
}
This will work out
public void AddMovie([FromBody] Movie movie) { }
Edit:
Remove JSON.stringify() Just assign the object itself

Unable to get fetch response on react native app

I am stuck on one of the mysterious issue. The problem goes like this:
What I Do??
Simply do login api call and if login success then I have to fetch amount of data from 5-6 api calls and store them in local database (Realm). Here is my code.
login(email, password) {
this.toggleLoadingFunction(true);
fetch(LoginURL, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
request_from: 'mobile'
}),
})
.then(async res => {
if (res.ok) {
let data = await res.json();
global.user = data['user']
global.token = data['token']
getAllMasterDataAndSaveInRealm().then(() => {
this.toggleLoadingFunction(false);
global.storage.save({ key: 'LoggedInData', data: data });
this.props.navigation.navigate('Project', data);
}).catch(() => {
this.toggleLoadingFunction(false);
Alert.alert("Master Data Failed !!!");
})
} else {
this.toggleLoadingFunction(false);
let data = await res.json();
Alert.alert("Login Failed!!!", data.message)
}
})
.catch(error => {
this.toggleLoadingFunction(false);
Alert.alert("Network Error. Please try again.")
})
Here getAllMasterDataAndSaveInRealm() is lies on helper function which calls 5-6 apis and response back if all work is done. Here is how it looks like:
export const getAllMasterDataAndSaveInRealm = () => {
const token = global.token;
return new Promise.all([
getMaterials(token),
getEquipments(token),
getObjective(token),
getCategories(token),
getNcData(token),
getPlans(token)]
);
}
Each function inside getAllMasterDataAndSaveInRealm() returns Promise after successfully stored data in local realm db. Here is one of the above function.
export const getActivityPlan = (token) => {
return new Promise((resolve, reject) => {
return fetch(FetchActivityPlanDataURL, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'access_token': `${token}`
}
}).then((response) => {
console.log("Activity Plans Api response", response);
return response.json()
})
.then((responseJson) => {
const { data } = responseJson
console.warn("Activity Plans Api", data);
global.realm.write(() => {
for (var item of data) {
item.id = item.id ? item.id : 0;
item.activity_id = item.activity_id ? item.activity_id.toString() : "";
item.activity_name = item.activity_name ? item.activity_name.toString() : "";
item.activity_cost = item.activity_cost ? item.activity_cost.toString() : "";
item.project_id = item.project_id ? item.project_id : 0;
global.realm.create("ActivityPlan", item, true);
}
})
resolve(data);
})
.catch((error) => {
reject(`Activity Plan Failed ${error}`)
});
})
}
All remaining functions are same as above ( what they do is simply fetch data from api and store it in realm and resolve or reject)
What I Expect:
getAllMasterDataAndSaveInRealm() function Just store all the required data in db and let me know all done and then navigate to the another screen, as Login and fetching data is done.
Problem:
When I do run the app and process for login, Sometimes it works fine but most of the time App stuck on showing loader since some of the api call among 6 api from above do not get response from the request ( I do log the response) on wifi. But when I use mobile data and VPN it always works.
When I log request on server console, response is sent with code 200, but app is unable to get response for the request.
I am new on react native. I do lots of searches over internet but unable to find the solution. I don't have any idea whats going wrong with the code. Please help me out.
Project Configurations:
"react": "16.8.6",
"react-native": "0.60.4",
"realm": "^2.29.2",
Node version: v9.0.0

Post action API with object parameter within the URL

I've got an API where some of the parameters need to be given within the URL.
Example of how my api url looks like: https://www.server.com/api/actions/execute?auth_type=apikey&data={"Name": "name","Email" : "email"}
What my code looks like right now
register = async () => {
let data = {"Name":this.state.name, "Email":this.state.email}
data = JSON.stringify(data)
let URL = 'https://www.server.com/api/actions/execute?auth_type=apikey&data=';
fetch(URL, {
method: 'POST',
headers: new Headers({
'Content-Type': 'application/json'
}),
body: data
})
.then((response) => response.text())
.then((responseText) => {
alert(responseText);
})
.catch((error) => {
console.error(error);
});
}
The response I get on my device:
{"code":"succes","details":{"userMessage":["java.lang.Object#2e56000c"],"output_type":void","id:"20620000000018001"},"message":"function executed succesfully"}
This is alle working fine when I test it in postman but I can't get it to work within React-Native. I've tried stuff like 'Content-Type':'application/x-www-form-urlencoded' already.
First install the package axios from the url https://www.npmjs.com/package/react-native-axios
Then create two service for handling get and post request so that you can reuse them
GetService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const GetService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.get(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
PostService.js
import axios from 'axios';
let constant = {
baseurl:'https://www.sampleurl.com/'
};
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Accept': 'application/json'
}
};
export const PostService = (data,Path,jwtKey) => {
if(jwtKey != ''){
axios.defaults.headers.common['Authorization'] = 'Bearer '+jwtKey;
}
try{
return axios.post(
constant.baseUrl+'api/'+Path,
data,
config
);
}catch(error){
console.warn(error);
}
}
Sample code for using get and post services is given below
import { PostService } from './PostService';
import { GetService } from './GetService';
let uploadData = new FormData();
uploadData.append('key1', this.state.value1);
uploadData.append('key2', this.state.value2);
//uploadData.append('uploads', { type: data.mime, uri: data.path, name: "samples" });
let jwtKey = ''; // Authentication key can be added here
PostService(uploadData, 'postUser.php', jwtKey).then((resp) => {
this.setState({ uploading: false });
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
GetService({}, 'getUser.php?uid='+uid, jwtKey).then((resp) => {
// resp.data will contain json data from server
}).catch(err => {
// handle error here
});
If you need to pass parameters via URL you should use GET, if you use POST then the parameters should be passed in the body

Problems passing parameters through the put method using fetch

I'm having problems trying to pass parameters by the put method using fetch
For this I am trying the following
fetch(`brands/${id}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({name: 'dummy text'})
})
.then(response => response.json())
.then(json => {
if (json.status === 'ok') {
// do some relevant logic
return false;
}
showErrors(json.errors);
})
.catch(error => console.error(error.message));
I am also trying using the FormData interface
const formData = new FormData();
formData.append('name', 'some dummy text');
fetch(`brands/${id}`, {
method: 'PUT',
body: formData
})
.then(response => response.json())
.then(json => {
if (json.status === 'ok') {
// Some relevant logic
return false;
}
showErrors(json.errors);
})
.catch(error => console.error(error.message));
But I am getting the same result (name parameter is not in the controller)
Inspected the network tab I can see that ajax has been called and in the params tab I can see that the variables are passed. But when trying to access these parameters from the controller they do not appear.
I appreciate your help
In backend when printing the parameters received in this query, the name parameter is not listed.
In backend the relevant parts in the controller definition are the following
The update method can only be invoked through the put method
static allowedMethods = [
save: 'POST',
update: 'PUT'
]
Here I hope that the name parameter has a value, but the parameter does not exist
def update() {
try {
Brand brand = brandService.update(params.id, params.name)
render(contentType: 'application/json') {
[status: 'ok', brand: brand]
}
} catch(ValidationException e) {
render(contentType: 'application/json') {
[status: 'fail', errors: e.errors]
}
}
}
Running your form through this little helper might do the trick:
form2Obj(form) {
const obj = {};
new FormData(form).forEach((val, key) => obj[key] = val);
return obj;
}

Categories

Resources