2

I'm working on a project client/server and I'm using spring boot and angular.

So I have a form and i want to take data from the input fields and send it to the back-end, my database ( mySQL ) but the problem is it only adds null fields in my database. I used a tutorial from devglen as inspiration and some tutorials from angular.io

Form input example:

<div class="form-group">
      <label for="body">Body:</label>
      <input type="text"  class="form-control" id="body"
             [ngModel]="article?.body" (ngModelChange)="article.body = $event" name="body">
    </div> 

Model class for the article i want to add:

export class Article {
  id: string;
  title: string;
  abstract_art: string;
  writer: string;
  body: string;
}

My component for adding:

@Component({
  selector: 'app-add',
  templateUrl: './add-article.component.html'
})



export class AddArticleComponent  {



   article: Article = new Article();
   writers: Writer[];

  constructor(private router: Router, private articleService: ArticleService) {

  }
  createArticle(): void {
    console.log(this.article);
    this.articleService.createArticle( this.article).subscribe( data => { alert('Article created successfully.');
    });
    console.log('function called!');
  }

  get diagnostic() { return JSON.stringify(this.article); }
}  

The service class:

const httpOptions = {
  headers: new HttpHeaders({ 'Content-Type': 'application/json',
    'Authorization': 'my-auth-token'})
};

@Injectable()
export class ArticleService {

  constructor(private http: HttpClient) {}

   // private userUrl = 'http://localhost:8080/articles';
  private articleUrl = '/api';

  public getArticles() {
    return this.http.get<Article[]>(this.articleUrl);
  }

  public deleteArticle(article) {
    return this.http.delete(this.articleUrl + '/' + article.id, httpOptions);
  }

  public createArticle(article) {
    // const art = JSON.stringify(article);
    console.log(article);
    return this.http.post<Article>(this.articleUrl, article);
  }

}

And now for the back-end. Article Class

@Entity
@Getter @Setter
@NoArgsConstructor
@ToString @EqualsAndHashCode
@Table(name="article")
public class Article {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    @Column(name="title")
    private String title;

    @Column(name="abstract_art")
    private String abstract_art;

    @Column(name="writer")
    private String writer;

    @Column(name="body")
    private String body;

    public Article(String title,String abstract_art, String writer, String body) {
        this.title = title;
        this.body = body;
        this.abstract_art = abstract_art;
        this.writer = writer;

    }
}

The repository :

@RepositoryRestResource
//@CrossOrigin(origins = "http://localhost:4200")
public interface ArticleRepository extends JpaRepository<Article,Integer> {
}

The article service:

@Service
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private ArticleRepository repository;

    @Override
    public Article create(Article article) {
        return repository.save(article);
    }

    @Override
    public Article delete(int id) {
        Article article = findById(id);
        if(article != null){
            repository.delete(article);
        }
        return article;
    }

    @Override
    public List<Article> findAll() {
        return repository.findAll();
    }

    @Override
    public Article findById(int id) {

        return repository.getOne(id);
    }

    @Override
    public Article update(Article art) {
        return null;
    }
}

And the controller:

@RestController
@RequestMapping({"/api"})
public class ArticleController {

   @Autowired
   private ArticleService article;

    //Get all articles
    @GetMapping
    public List<Article> listAll(){
        return article.findAll();
    }

    // Create a new Article
    //@PostMapping
    @PostMapping
    public Article createArticle(Article art) {
        return article.create(art);
    }

    // Get a Single Article
    @GetMapping(value="/{id}")
    public Article getArticleById(@PathVariable("id") int id ){
        return article.findById(id);
    }

    // Delete a Note           /art/

    @DeleteMapping(value = "/{id}")
    public void deleteArticle(@PathVariable("id") int id) {
        article.delete(id);
    }

    @PutMapping
    public Article update(Article user){
        return article.update(user);
    }
}

In the picture you can see that it creates my json object but when i'm adding it to the database it only adds null values.

Additional information: I can get data from database and I can delete data from database.

Btw it's my first post so i'm sorry if i've missed some guidelines for posting. Thank you in advance for your answers. Have a good one!

5
  • try this and see public Article createArticle(@RequestBody Article art) Commented May 20, 2018 at 17:07
  • @Vikas hahaa it worked ! Thank you so much! But i thought if i had the "@RestController" annotation i don't have to add the "@RequestBody" ? Commented May 20, 2018 at 17:10
  • @StefanMuresan @RestController annotation is short-hand for the @Controller and @ResponseBody. @ResponseBody just assures you that return type should be written straight to the HTTP response body. Thus you need to use the @RequestBody annotation to bound the parameter to the body of HTTP request. Commented May 20, 2018 at 17:20
  • I have answered your question mark it if it helped Commented May 20, 2018 at 17:28
  • Thank you @pulkit-singhal for your answer!! Commented May 20, 2018 at 17:28

2 Answers 2

5

@RestController is a convenience annotation that does nothing more than adding the @Controller and @ResponseBody annotations as well as allows the class to accept the requests that are sent to its path

@DOCS
@ResponseBody annotation tells a controller that the object returned is automatically serialized into JSON and passed back into the HttpResponse object.

@RequestBody annotation maps the HttpRequest body to a transfer or domain object, enabling automatic deserialization of the inbound HttpRequest body onto a Java object.

You missed @RequestBody
@RequestBody marks that the Article input is retrieved from the body/content of the POST request. This is a notable difference between GET and POST as the GET request does not contain a body.

Modified code

 @PostMapping
    public Article createArticle(@RequestBody Article art) {
        return article.create(art);
    }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you @Vikas!!
0

You will also see weird stuff like this because of the naming. I think the JPA assumes name like my_stuff to be my_Stuff.

So I always use Postman after I am done building my controller to test a post or get.

When Postman gives you back the raw json, take note of the naming of all properties, because the casing matters.

1 Comment

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

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.