0

the ng-repeat model doesn't update after a user clicks submit, it will only show on refresh, i reviewed a similar problem, but i couldn't connect the dots. A user recommended i do a ng-init, but i don't think im doing it right.

with ng-init it shows no data, without ng-init and removing the angular function it shows posts but doesn't update the model after click.

note:the angular brackets are replaced because laravel blade doesn't like it

html

    <div id="mypost" class="col-md-8 panel-default" ng-init="getPosts()" ng-repeat="post in myposts">
        <div id="eli-style-heading" class="panel-heading"><% post.title %></div>
            <div class="panel-body panel">
                <figure>
                    <p> <% post.body %></p>

                </figure>
            </div>


    </div>

Main.js

// this doens't show posts when i use ng-init
$scope.getPosts = function(){

    $http.get('/auth/posts').then(function(data){
        $scope.myposts = data.data;
    });



};

// this shows posts without ng-init but doesn't update when a user adds data


$http.get('/auth/posts').then(function(data){
    $scope.myposts = data.data;
});

Updated Again

network error

enter image description here

enter image description here

PostController.php

public function storePost(Request $request)
{
    $data = request()->validate([
     'title' => 'required|max:120',
     'body' => 'required|max:1000'
    ]);

    $data['user_id'] = auth()->user()->id;

    $post = Post::create($data);


    // return redirect('/home')->withMessage('A new post was created.');

    return Response::json(array('success' => true));
}

enter image description here

BARNOWL
  • 3,326
  • 10
  • 44
  • 80
  • angular doesn't understand the blade syntax. Consider using `ng-bind` if Laravel is throwing errors on the mustache syntax. – Steve Danner Nov 14 '17 at 21:21
  • Have you tried adding a `$scope.$apply();` after you assign the data to `$scope.myposts`? The problem is that the promise resolution is outside of Angular's digest cycle so it doesn't know that it needs to refresh the UI unless you tell it to. – Lex Nov 14 '17 at 21:22
  • @SteveDanner ng-bind didn't work im still unable to see posts. – BARNOWL Nov 14 '17 at 21:25
  • @Lex i tried that, i still was unable to see posts – BARNOWL Nov 14 '17 at 21:26
  • if i remove the get posts function, and just leave it as `$http.get('/auth/posts').then(function(data){ $scope.myposts = data.data; });` and remove the ng-init i can see the posts but then again it doesn't update when a post has been made – BARNOWL Nov 14 '17 at 21:28
  • @SteveDanner this is what i currently got, https://jsfiddle.net/xf20j22u/ – BARNOWL Nov 14 '17 at 21:32
  • @OwlMan please provide the $scope.http.post request ... – Sorikairo Nov 14 '17 at 22:13
  • @OwlMan If your code is the same as the fiddlejs, you MISTYPED your variable name ! You wrote $scope.POSTS.push(data), instead of $scope.MYPOSTS.push(data) !! – Sorikairo Nov 14 '17 at 22:15

2 Answers2

1

Don't use ng-init except in cases where you are aliasing a special property of ng-repeat like $last or $even for nested ng-repeats. If you want a function to trigger immediately just call it in the controller or service/factory it is defined in.

https://jsfiddle.net/xf20j22u/1/

var app = angular.module('eli', []);

app.config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('<%');
    $interpolateProvider.endSymbol('%>');
});

app.controller('mainCtrl', function($scope, $http, $timeout){
 $scope.posts = {};
  $scope.myposts = [{title:"titillating title",body:"Hot boddy"}]
 $scope.addPost = function(){
  
  $http.post('/auth/post', {
   title: $scope.post.title,
   body: $scope.post.body

  }).then(function(data, status, headers, config){
   $scope.posts.push(data); 
  
  });

 };

 $scope.getPosts = function(){

  $timeout(function(){
          debugger;
          $scope.myposts = [{title:"something new",body:"It's my body"}]
        },3000)
  //$http.get('/auth/posts').then(function(data){
  // $scope.myposts = data.data;
  // $scope.$apply();
  //});
 };
  $scope.getPosts();



});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.js"></script>
<div  ng-app="eli" ng-controller="mainCtrl">
  
  <div id="mypost" class="col-md-8 panel-default" ng-repeat="post in myposts">
    <div id="eli-style-heading" class="panel-heading">
      <% post.title %>
    </div>
    <div class="panel-body panel">
      <figure>
        <p>
          <% post.body %>
        </p>

      </figure>
    </div>
  </div>
</div>

Working version above can replace $timeout with $http they both call $apply for you so don't call it again (only need to call $apply if you write your own things that async do work then update the model and you want to trigger a view refresh, angular event handlers and services do it for you)

shaunhusain
  • 19,630
  • 4
  • 38
  • 51
  • thank you will keep that in mind for sure, but that still doesn't solve my problem. I can retrieve posts without ng-init but it will not update on when a user trys to add a post. – BARNOWL Nov 14 '17 at 21:40
  • Think ng-bind and things were just getting in the way really can't say exactly what's wrong since I had to add some context for getting the ng-app and controller running there, in place of the timeout could use $http, both $http and $timeout (and all the handlers like ng-click) call $apply for you under the hood. – shaunhusain Nov 14 '17 at 21:51
  • i appreciate your effort, but im still having the same problem, a user can add a post ok, but it just doesn't update( the ajax way) only on refresh it shows the new data, ill upvote it but it doesn't solve my problem. – BARNOWL Nov 14 '17 at 21:56
  • No problem :). Drop a `debugger;` statement in the success callback and make sure it actually does the call to push the item into the array if not check the network tab to see if the response is a 200 OK or something else – shaunhusain Nov 14 '17 at 21:58
  • @OwlMan shaunhusain said it earlier. Your callback isn't called, thus the array isn't updated because you never enter the callback. – Sorikairo Nov 14 '17 at 21:59
  • @Sorikairo what should i put in the callback ?. im starting to understand the problem. – BARNOWL Nov 14 '17 at 22:00
  • @OwlMan the problem seems to be serverside. The post request may never answer, so the callback isn't called. Check your code server side :) – Sorikairo Nov 14 '17 at 22:02
  • ~angular.js:12701 XHR finished loading: GET "http://127.0.0.1:8000/auth/posts".` looks fine – BARNOWL Nov 14 '17 at 22:03
  • however, when i add a post i get this `angular.js:12701 POST http://127.0.0.1:8000/auth/post 500` but when i refresh the page i see my new post – BARNOWL Nov 14 '17 at 22:03
  • Hit F12 in chrome then go to the network tab and just make sure when you trigger the call out on page load or whenever it actually gives a 200 OK from the browser perspective, sounds alright but good to see the response the browse got.... yeah so 500 is internal server error angular will trigger error response callback for that not success, the server needs to respond that all is well, so server side issue or bad request object or something making the server puke all over itself....gross – shaunhusain Nov 14 '17 at 22:04
  • @OwlMan Wait ! Can you post your POST request call code ? It's where the problem is. You have a 500 error, so it doesn't answer properly to your call, so your callback aren't called. – Sorikairo Nov 14 '17 at 22:05
  • @OwlMan you forgot to put the most important piece of code, the post request made in angular is the key. You probably forgot to put an error callback, and it doesn't call your success callback as it's a 500 – Sorikairo Nov 14 '17 at 22:07
  • @Sorikairo i just updated tell me what you think, thanks – BARNOWL Nov 14 '17 at 22:12
  • @OwlMan missing the $scope.http.post part, which is the key :/ – Sorikairo Nov 14 '17 at 22:13
  • I did, i just updated. are you talking about something else. – BARNOWL Nov 14 '17 at 22:15
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/159009/discussion-between-sorikairo-and-owl-man). – Sorikairo Nov 14 '17 at 22:17
1

With the help of another @Sorikairo we were able to solve the problem, i didn't want to post the answer because i was lazy, but i need to help the people who ever encounter a very similar problem when using laravel. Here is the updated code.

Main.js

var app = angular.module('eli', []);

app.config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('<%');
    $interpolateProvider.endSymbol('%>');
});

app.controller('mainCtrl', ['$scope', '$http', function($scope, $http){


    $scope.posts = {};

    $scope.addPost = function(){

        $http.post('/auth/post', {
            title: $scope.post.title,
            body: $scope.post.body

        }).then(function(data, status, headers, config){
            console.log(data);  
            $scope.myposts.push(data.data);


        });

        $scope.post.title = '';
        $scope.post.body = '';

    };

    $scope.getPosts = function(){

        $http.get('/auth/posts').then(function(data){
            $scope.myposts = data.data;
        }).then(function(data, status, header, config){
        });



    };


    $scope.getPosts();





}]);

i needed to add

the response class to my php file

<?php

namespace App\Http\Controllers;

use App\Post;
use App\User;
use Illuminate\Http\Request;
use Illuminate\Http\Response;

class PostController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        //
    }

    /**
     * Show the form for creating a new resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function create()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
     */
    public function storePost(Request $request)
    {
        $data = request()->validate([
         'title' => 'required|max:120',
         'body' => 'required|max:1000'
        ]);

        $data['user_id'] = auth()->user()->id;

        $post = Post::create($data);

        $response = new Response(json_encode($data));
        $response->headers->set('Content-Type', 'application/json'); 


        // return redirect('/home')->withMessage('A new post was created.');

        return $response;
    }

it works now thank you everyone

BARNOWL
  • 3,326
  • 10
  • 44
  • 80