1

I have an Angular JS and Laravel app. One of my form feilds is an ng-options driven select. The values are strings but when I post using http.post, one of the values seems to be getting converted to an array.

I have this in my JS controller for the options;

    $scope.periods = [
    {label: '1'},
    {label: '2'},
    {label: '3'},
    {label: 'OT'}
];

This is my view for the select;

<select ng-model="egoal.period"
        ng-options="period.label as period.label for period in periods"
        class="form-control game-control"
        required>
</select>

And then this in the controller to post;

  $scope.changeGoal = function() {
        var egoal = this.egoal;
        $http.post('api/editGoal/' + this.goal.id, egoal)
            .success(function () {
                $scope.egoal = {};
            });
};

Oddly, when I dump the $request, I get period => [] and then this error;

ErrorException in helpers.php line 685: preg_replace(): Parameter mismatch, pattern is a string while replacement is an array

Been looking at this for a long time now. What could be causing this?
Thanks!

UPDATE: Egoal object looks like this after the selection is made;

EGoal: {
  "id": 268,
  "game": 147,
  "season": 4,
  "team_id": 2,
  "period": "2",
  "min": 7,
  "sec": 54,
  "scorer": 11,
}

but the period value is converted on post to an empty array...

3 Answers 3

1
  $scope.changeGoal = function() {
        var egoal = this.egoal;
        $http.post('api/editGoal/' + this.goal.id, egoal)

A function in javascript is a block with its own scope. You need to use the vm concept. https://github.com/johnpapa/angular-styleguide/tree/master/a1#controlleras-with-vm

In the context of the changeGoal function, this.egoal is undefined.

Sending undefined as data to $http.post somehow serializes it to an empty array.

Sign up to request clarification or add additional context in comments.

5 Comments

Probably because php "objects" are called arrays? Maybe not in Laravel.
Ok, I am following. Just prior to the changeGoal form being loaded I am declaring egoal though. So I can in fact print egoal to the view and see that the form and model binding are working as expected - changing egoal.period changes it in the model. All good until I hit the post.
Inside the changeGoal function, try a console.log(this.egoal). It will be undefined. A function in javascript is a block with its own scope. You need to use the vm concept github.com/johnpapa/angular-styleguide/tree/master/…
Ah! Getting somewhere. Not undefined but period is coming through as an object not a value. How's that?
I don't know what you're seeing or where. What is sure is if the function is exactly like it is in your question, then this.egoal is undefined when passed to $http.post. Use $scope.egoal instead of this.egoal and make a fiddle reproducing your issue if it still doesn't work.
0

From the ngOptions docs:

When an item in the menu is selected, the array element or object property represented by the selected option will be bound to the model identified by the ngModel directive.

So, when you select one of the items from the dropdown, your ngModel egoal.period is not 1, or 2, or 3, or OT, it's {label: '1'}, {label: '2'}, etc. It's actually a pointer to the one of the items in your $scope.periods array.

Check out this plunker to get a better idea of what I mean: http://embed.plnkr.co/9cJ2Hy/

Your PHP script is probably expecting a json object like this:

{
  ...
  "period": '1',
  ...
}

But it's actually getting something more like this:

{
  ...
  "period": "{\"label\": '1'}",
  ...
}

6 Comments

Hey JoelCDoyle. I am following but I am using ng-model='egoal.period' for the select. So, when I print the egoal object to my view I do see period as an attribute and the label as the value. Are you saying that's not actually what's happening?
Will you post what the print out of the egoal object looks like? You can limit it to just the relevant part.
See UPDATE in question.
Ok, this answer is not right then. Since you are using period.label as period.label then you are doing it right already.
Thanks - thought I was anyway - still stumped tho. BTW - you're a dead ringer for Col. Les Claypool!
|
0

AngularJS uses JSON object by default in $http.post .

You can change the default setting by adding a correct Content-Type header to the config object:

headers : { 'Content-Type': 'application/x-www-form-urlencoded' } 

UPDATE:

... by simply adding:

angular.module('myApp', [])
        .config(function ($httpProvider) {
            $httpProvider.defaults.headers.put['Content-Type'] = 'application/x-www-form-urlencoded';
            $httpProvider.defaults.headers.post['Content-Type'] =  'application/x-www-form-urlencoded';
        })

Or another solution would be:

return $http({
         method: 'POST',
         url: "/yoururl/",
         data:{
            'param1': "Test",
         },
         headers: {
             'Content-Type': 'application/x-www-form-urlencoded'
         }}).then(function(result) {
             console.log(result);
         }, function(error) {
             console.log(error);
         });

3 Comments

Sounds fair. LIttle confused on what you mean by adding a correct Content-Type header to the config object:
Ok, added that. Now whaen I dump my request I get an array and period is now an empty object.
array:1 [ "{"id":268,"game":147,"season":4,"team":"Olden_Hawks","team_id":2,"period":{},"min":7,"sec":54,"scorer":11,"scorerId":91,"assist1":13,"assist1Id":null,"assist2":null,"assist2Id":null,"empty":0,"short":0,"created_at":"2016-09-12_20:35:04","updated_at":"2016-11-14_15:59:08"}" => "" ]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.