I'm trying to build a little Angular 4 Application with a rest api build with slim php. I'm having touble to access the POST variables on specific routes, while it works perfectly on at least one route. Here is my code:
// Log In A League { "email": $email, "pass": $pass }
$app->post('/api/users/league-login', function(Request $request, Response $response){
require "user_management/league_login.php";
$logIn = new LeagueLogIn();
$logIn->logIn($request->getParam("email"), $request->getParam("pass"));
});
Angular sends this JSON:
Object { email: “test#test.com", pass: "000" }
This works perfectly. But on this rout I can't access the POST variables with $request->getParam()
// Add Team To A League { "name": $name, "email": $email }
$app->post('/api/league/team', function(Request $request, Response $response){
require "user_management/team_create.php";
$user = authorizeToken($request->getHeader('Authorization'));
$teamCreate = new TeamCreate();
$teamCreate->create($request->getParam("name"), $request->getParam("email"), $user);
});
Angular sends this JSON
Object { name: "name", email: "test2#test.com" }
As soon as I add double quotes on the keys manually for the request:
Object { "name": "name", "email": "test2#test.com" }
it works perfectly.
Does somebody know what kind of problem this is, or what I'm overlooking?
Related
I am learning the basics of Angular and am currently working on making a REST service using the HttpClient from #angular/common/http.
In many tutorials the first step is making a http.get() call. Usually first the whole list following a http.get() call focused on retrieving only one element. In my example, I have a userList (with users). I have made two methods: getUserById() and getUserByName(). ${this.userUrl} refers to the location of the database (using a JSON file) Below they are displayed:
constructor(private http: HttpClient) {
}
getUserById(id: number): Observable<IUser> {
return this.http.get<IUser>(`${this.userUrl}/${id}`);
}
getUserByName(name: string): Observable<IUser> {
return this.http.get<IUser>(`${this.userUrl}/?name=${name}`);
}
Initially I tried to make the getUserByName() method work via the same way the getUserById(). Thus using:
getUserByName(name: string): Observable<IUser> {
return this.http.get<IUser>(`${this.userUrl}/${name}`);
}
This didn't work and I received the error statement 404 file not found. This is the json file that I worked with (I have set up a json server so that I could also perform http.delete() methods and so on):
{"users": [
{
"id": 1,
"name": "James",
"lastName": "Jameson",
"dateOfBirth": "10-10-2000",
"occupation": "Student"
},
{
"id": 3,
"name": "Steven",
"lastName": "Stevenson",
"dateOfBirth": "10-10-1990",
"occupation": "Police officer"
}]}
Can anyone explain me why the getUserById methods works using just '/${id}' in the url call and why the getUserByName needs to use '?/name=${name}'?
if you use:
getUserById(id: number): Observable<IUser> {
return this.http.get<IUser>(`${this.userUrl}/${id}`);
}
getUserByName(name: string): Observable<IUser> {
return this.http.get<IUser>(`${this.userUrl}/${name}`);
}
and call for exemple /user3262578, it will enter to the first endpoint method which is getUserById(id), you're clearly have ambiguity here. the both methode have the same endpoints.
try to change the second endpoint (getUserByName) to other link like:
return this.http.get<IUser>(`${this.userUrl}/search/${name}`);
This is nothing to do with Angular, this is purely a backend endpoint issue.
Test requests to your backend using an HTTP Rest Client such as PostMan.
Once everything is working at the backend as expected, then integrate with Angular.
I am writing an API to consume data from another 3rd party application (RapidPro). Sadly, the third party application sends its JSon enclosed in single quotes which Laravel does not seem to understand, when I return the $request object, I get an empty array [].
Is there any way I can accept the JSon as it is with single quotes as I cannot possibly change the third party API?
The JSon to parse is this one:
{
'contact': {
'uuid': 'e65ef92b-24ce-459b-a8fd-beb042330eb0',
'name': 'UserName',
'urn': 'tel: +12000000000'
},
'flow': {
'name': 'MyFlow',
'uuid': 'da5d6c42-a818-481b-b91c-e9622dafe8be'
},
'path': [],
'results': {},
'run': {
'uuid': '2a2f709f-d114-413c-a865-d960cea73981',
'created_on': '2018-05-23T19: 06: 03.308191+00: 00'
},
'input': {
'urn': 'tel: +12000000100',
'text': 'What I wanna say',
'attachments': []
}
}
I user the following route in receiving the API call, it works and takes it to the controller:
Route::post('sms', 'UserController#sms')->name('sms.store');
The SMS controller for this demo let's just write it to a local file and send back the results to be viewed in Insomnia where the demo call is made:
public function sms(Request $request)
{
Storage::put('sms.txt', $request);
return $request;
}
When I post the JSON in via Insomnia to my server I get an empty response, when I use double quotes however; the posted JSON is thrown back nicely.
Turns out, in RapidPro debugger the jSON is shown using single-quotes but in actual POST it uses double quotes. What I had wrong was the AUTH. I had to include some header for Laravel's Basic Once authentication.
By nested json I mean something that keeps address data in its own "address" array:
{
"user": {
"id": 999,
"username": "xxxx",
"email": "xxxx#example.org",
"address": {
"street": "13th avenue",
"place": 12
}
}
}
instead of flat one
{
"user": {
"id": 999,
"username": "xxxx",
"email": "xxxx#example.org",
"street": "13th avenue",
"place": 12
}
}
Flat one is processed fine there using User entity and it's properties: "id", "username" and "email". It is nicely validated using symfony form feature:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('username');
$builder->add('email', 'email');
$builder->add('password', 'password');
$builder->add('street');
$builder->add('place');
}
I want to have both "street" and "place" as properties in User entity, to store it all in one user table in the database, using doctrine. But the json I get comes from third party, so I can not modify it.
Is there any way of constructing the form so it can validate the json with "address" field correctly, still being able to keep all the user data in one table?
This is a pretty good question. One solution that comes to mind is making an unmapped form and binding data manually using a form event, for example:
public function buildForm(FormBuilderInterface $builder, array $options)
{
// Make a "nested" address form to resemble JSON structure
$addressBuilder = $builder->create('address', 'form')
->add('place')
->add('street');
$builder->add('username');
$builder->add('email', 'email');
$builder->add('password', 'password');
// add that subform to main form, and make it unmapped
// this will tell symfony not to bind any data to user object
$builder->add($addressBuilder, null, ['mapped' => false]);
// Once form is submitted, get data from address form
// and set it on user object manually
$builder->addEventListener(FormEvents::POST_SUBMIT, function (FormEvent $event) {
$user = $event->getData();
$addressData = $event->getForm()->get('address')->getData();
$user->setStreet($addressData['street']);
$user->setPlace($addressData['place']);
})
}
I've started sending mails through Laravel (4.2) and its embedded Mandrill driver these days, but I need to catch Mandrill's response somehow.
Here's the code I use to send the message:
Mail::queue('emails.customerspromo', array('messaggio'=>$content, 'disclaimer'=>$disclaimer, 'user_email'=>$to, 'user_id'=>$uid), function($message) use ($sender, $to, $subject) {
$message->from('my#address.it', $sender);
$message->to($to);
$message->subject($subject);
$message->setCharset('UTF-8');
$message->getHeaders()->addTextHeader('X-MC-GoogleAnalytics', 'www.my-site.it');
$message->getHeaders()->addTextHeader('X-MC-GoogleAnalyticsCampaign', 'my-campaign');
});
What I need to intercept is Mandrill's JSON response, for example:
[
{
"email": "destination#address.com",
"status": "sent",
"_id": "80e1ca49d3ed4cbb9d9a3d932c0a14f8",
"reject_reason": null
}
]
How can I do that using Laravel's integrated drivers for Mandrill?
I could use Mail::send instead of Mail::queue, if it's necessary to interpret the response in real time.
Put a variable before your mail function like this:
$response = Mail::queue('emails.customerspromo', array('messaggio'=>$content, 'disclaimer'=>$disclaimer, 'user_email'=>$to, 'user_id'=>$uid), function($message) use ($sender, $to, $subject) {
$message->from('my#address.it', $sender);
$message->to($to);
$message->subject($subject);
$message->setCharset('UTF-8');
$message->getHeaders()->addTextHeader('X-MC-GoogleAnalytics', 'www.my-site.it');
$message->getHeaders()->addTextHeader('X-MC-GoogleAnalyticsCampaign', 'my-campaign');
});
It will still work but now you can see the response from mandrill.
I've got a node application that uses express, socket.io 1.0 and passport. When a user auths through passport-twitter I store their information in a session store using the below code;
var passportSocketIo = require("passport.socketio");
var MemoryStore = express.session.MemoryStore
,sessionStore = new MemoryStore();
io.set('authorization', passportSocketIo.authorize({
cookieParser: express.cookieParser,
key: 'express.sid',
secret: 'secret',
store: sessionStore
}));
I then use the following for my socket.io connection handler;
io.on("connection", function(client){
console.log(sessionStore.sessions[client.request.sessionID]);
});
This returns all the session data for the client with that ID in this format;
{
"cookie": {
"originalMaxAge": null,
"expires": null,
"httpOnly": true,
"path": "/"
},
"passport": {
"user": {
"id": "XXXXXXXXXX",
[...],
[...]
}
}
}
The issue is that if I tried to access "passport" from the structure, the result is always undefined. I tried the following (both with and without the . before "passport");
sessionStore.sessions[client.request.sessionID].[passport]
sessionStore.sessions[client.request.sessionID].["passport"]
sessionStore.sessions[client.request.sessionID].passport
sessionStore.sessions[client.request.sessionID]."passport"
Unfortunately these return as undefined. I'm really just trying to get the passport.user.id field value out of that structure so I can perform some DB lookup (e.g. user group, user privacy settings, etc) and so I can ensure I emit the correct DB data back to the client.
Any ideas?
After looking into it further, it appears that passing it through JSON.parse() was the correct method to use;
var jsobj = JSON.parse(sessionStore.sessions[client.request.sessionID]);
console.log(jsobj.passport.user.id);
or for a single line solution;
console.log(JSON.parse(sessionStore.sessions[client.request.sessionID]).passport.user.id);