0
votes

I'm trying to add new data to old one's without refreshing page, the issue is when I add new one not only new data but old data return with it as well.

Example

Here I have 2 bid (old data)

one

When I add new bid it supposed to become 3 instead it becomes 5

two

which means my 2 old data stays as they are and again they return with new one 3 total becomes 5

Code commented

data() {
    return {
        bid: { //send bid to back-end (form)
            attachment: '',
            message: '',
            bid: '',
            project_id: '',
            user_id: '',
        },
        biders: [],  //return old bids info
        new_biders: '',
    }
},
mounted: function () {
    this.getBidders(); // get old bids info
},
sendbid() { //send bid form data to back-end
    let project_id = this.project.id;
    let message = this.bid.message;
    let user_id = this.user.id;
    let attachment = this.bid.attachment;
    let bid = this.bid.bid;
    axios.post('/api/sendbid', {project_id, user_id, message, attachment, bid})
        .then(response => {
            $(".bidmsg").append('<div class="alert alert-success" role="alert">Thank you dear <b>' + this.user.name + '</b> your bid placed successfully.</div>');
            //get new bid data and add it to previous ones
            this.$nextTick(function () {
                this.getBidders();
            });
        });
},
getBidders: function () { // get previous (old data) bids info
    let url = `/api/projects/${this.$route.params.slug}`
    axios.get(url).then(function (response) {
        this.project = response.data;
        axios.post('/api/projectbids/' + this.project.id)
            .then(function (res) {
                _.forEach(res.data, function (item) {
                        this.biders.push(item);
                    }.bind(this)
                )
            }.bind(this))
            .catch(error => {
                console.log(error.response)
            });

        Echo.private('newbidplaced.' + this.project.id)
            .listen('NewBider', function (e) {
                this.biders.push(e.bider);
            }.bind(this));

        Vue.nextTick(function () {
            $('[data-toggle="tooltip"]').tooltip()
        });
    }.bind(this));

}

Question

  1. How can I only return new data without old ones?

this part in sendbid():

this.$nextTick(function () {
  this.getBidders();
});
2
when you are adding new bid ,In response you are getting all the bids not the one added and then you are appending it to the existing one so its duplicating data.So I think one way is return only those that are added last.Mayuri Pansuriya
You're only ever pushing to the bidder's array, never pruning: this.biders.push(item);. Do you mean to do this.bidders.splice(0, this.bidders.length, res.data)?Brian Lee
@MayuriPansuriya exactly that's my issue (i'm aware of that, as i call my getBidders()) but the issue is i don't know how to return only new one?mafortis
@DigitalDrifter i'm getting Error in nextTick: "TypeError: this.bidders is undefined" with splice method.mafortis
the data property: biders:[], //return old bids info, I used two d's in my spelling.Brian Lee

2 Answers

1
votes

You have to push the element you just added, getBidders is not really necessary, but if you want to still use getBidders, you have to clone the response instead of pushing to the array, since it already has those values. Or check in this.bidders if the object already exist in the array.

You can try at least refreshing the array, but it may flash on the page...

Sol1

this.bidders = [] // empty the array before adding new data
_.forEach(res.data, function(item){
   this.bidders.push(item);
}.bind(this)

Sol2

As i said before, you should return the saved element at sendbid() method.

And add this element to bidders. That would be a more appropiate approach.

Just append (push) or prepend (unshift), instead of calling the getBidders function...

this.bidders.push(response);
this.bidders.unshift(response);

Should end up with something like

axios.post('/api/sendbid', {project_id, user_id, message, attachment, bid})
.then(response => {

    if(response.data.status == 'ok'){
        $(".bidmsg").append('<div class="alert alert-success" role="alert">Thank you dear <b>'+this.user.name+'</b> your bid placed successfully.</div>');
        // use either push or unshif not both, of course you already know that.
        this.bidders.push(response.data.bid);
        this.bidders.unshift(response.data.bid);

    }


});

Also in the function that gets called by api/sendbid route... add something like:

Assuming you have a Bid Model, and that you just saved a bider;

    $bid->save(); //when you call the save function automatically updates the inserted id.

    $data['status'] = 'ok';
    $data['bid'] = Bid::findOrFail($bid->id); //this will refresh the element so everything is passed correctly.

    return response()->json($data);
0
votes

try

let removeIndex = this.yourData.map(function (data) {
                                    return data.id;
                                }).indexOf(id);
                                this.yourData.splice(removeIndex, 1);

hope this helps