How to push Object element to an array in Vuejs/Javascript - javascript

I'm trying to build a small application in VueJs,
Following is my data set:
data(){
return {
pusher: '',
channel:'',
notify: [],
notifications: '',
notificationsNumber: '',
}
},
where I'm having an axios call in created property of components as:
axios.get('api/notifications', {headers: getHeader()}).then(response => {
if(response.status === 200)
{
this.notify = response.data.notifications
this.notificationsNumber = this.notify.length
}
}).catch(errors => {
console.log(errors);
})
I'm having pusherJs implemented, so I'm having following code:
this.pusher = new Pusher('xxxxxxxx', {
cluster: 'ap2',
encrypted: true
});
var that = this
this.channel = this.pusher.subscribe('stellar_task');
this.channel.bind('company_info', function(data) {
console.log(data.notification);
that.notifications = data.notification
});
Once the value is being obtained from pusher I want to push this to my array notify as watch property, something like this:
watch: {
notifications(newValue) {
this.notify.push(newValue)
this.notificationsNumber = this.notificationsNumber + 1
}
}
So the problem is the data format which I'm receiving through pusher is in object form and push function is not getting implemented in this:
Screenshot:
Help me out with this.

I'm making an assumption that response.data.notifications is an Array Like Object.
So all you have to do is:
this.notify = [...response.data.notifications];

Related

My object javascript is not fully sent to the back

I'm trying to send an object from front to back.
this is my function :
export const addComponent = (newComponent, inputFields) => (dispatch) => {
const url = process.env.REACT_APP_ADD_COMPONENT;
var componentBody = {
type: newComponent.type,
name: newComponent.name,
};
var componentTest = inputFields.map((inputField) => {
return Object.defineProperty(componentBody, inputField.property, {
value: inputField.content,
});
});
console.log(componentTest);
axios
.put(url, componentTest)
.then(dispatch({ type: ADD_COMPONENT, payload: componentTest }))
.catch((err) => {
console.log("Add failed", err);
});
};
When I log componentTest, it get the strucutre that I want, which mean :
{
description: "je décris",
environnement: "j'environne",
name: "test",
type: "Données"
}
But on the backside, in my route when I log req.body, there is only type and name which are present. Like if the defineProperty function doesn't records my object...
I presume that i need to enumerate all the properties of my object, but my knowledges stop here
I founded it,
If someone else need it.
With defineProperty you need to configure your new object by adding :
var componentTest = inputFields.map((inputField) => {
return Object.defineProperty(componentBody, inputField.property, {
value: inputField.content,
writable: true,
enumerable: true,
configurable: true,
});
});
Now i can see my object fully.

Erro when trying to push to array from http request in vue.js

I'm trying to push an object into a response from a axios get request, but i always got an 'push is not a function' error
i'm trying to push inside the .then block of the http request
ps: i'm following the example from the vuejs site
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!',
bitCoinValue: null
},
mounted() {
this.getBitcoinValue();
},
filters: {
currencydecimal(value) {
return value.toFixed(2);
}
},
methods: {
getBitcoinValue: function () {
axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => {
this.bitCoinValue = response.data.bpi || [];
this.bitCoinValue.push({code: 'BRL', description: 'Reais', symbol: 'R$', rate_float: 25.50});
});
}
}
})
this is the error message:
Uncaught (in promise) TypeError: this.bitCoinValue.push is not a function
at site.js:21
the problem is that your response from https://api.coindesk.com/v1/bpi/currentprice.json the bpi entry is a Object therefore you can not use push because it is a function for the Array Object.
you have 2 options:
set your value as the similar approach that the api responds
getBitcoinValue: function () {
axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => {
this.bitCoinValue = response.data.bpi || [];
this.bitCoinValue['BRL'] = {code: 'BRL', description: 'Reais', symbol: 'R$', rate_float: 25.50};
});
}
convert the object to array then push
getBitcoinValue: function () {
axios.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => {
let objectResponse = response.data.bpi || {};
this.bitconValue = Object.values(objectResponse).map(item => item)
this.bitCoinValue['BRL'] = {code: 'BRL', description: 'Reais', symbol: 'R$', rate_float: 25.50};
});
}
Openig your API endpoint in a browser, I found out that the "bpi" key in the response JSON is not an array but rather an object. So, instead of .push()ing a value, you need to set the key directly, i.e. this.bitCoinValue.BRL = {...};.

reactJS map function not working as expected

I have a reactJS application where I am trying to dynamically render some data that I read in with a fetch() promise. This is the code of my application:
import React from 'react';
import '../styles/app.css';
//think of react components as functions
class Testpage2 extends React.Component {
constructor(props) {
super(props);
this.state = {
numberOfRecords: 0,
productArray: [{
barcode: '',
name: ''
}]
};
}
componentDidMount() {
let currentComponent = this;
var recordCount = 0;
var tempData = [];
//Make use of the API not the web service.
let url = "http://wmjwwebapi-dev.us-west-2.elasticbeanstalk.com/api/getdata";
const options = { method: 'GET' };
fetch(url, options)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
if (myJson == undefined)
{
console.log("fetch failed");
}
else
{
//inspect the data that the WebAPI returned
var return_code = myJson[0].return_code;
if (return_code == "Default Return code"){
recordCount = -2;
} else {
tempData = JSON.parse(myJson[0].return_string);
recordCount = tempData.barcode.length;
}
currentComponent.setState(
{
numberOfRecords: recordCount,
productArray: currentComponent.state.productArray.push(
{
name: tempData.name,
barcode: tempData.barcode
})
}
);
}
});
}
render() {
console.log(this.state.productArray);
return (
<div>
{ this.state.productArray.map((prod, index) => <li key={index}>{prod.barcode}</li>)}
</div>
)
}
}
export default Testpage2
and this is the error message that I am getting:
Uncaught (in promise) TypeError: this.state.productArray.map is not a function
at Testpage2.render (testpage2.js:67)
This is the result of the console.log() that I added in the render() function:
I'm not really sure what this error is telling me or how to go about debugging the issue.
Any help is greatly appreciated.
Thank you.
The return type of array.push is the new length of the array aka a number
So you set the state property productArray to a number and then try to call number.map which is not defined
How to fix?
push first and then use that array to set the state
const updatedArray = [...currentComponent.state.productArray]
updatedArray.push({ name: tempData.name, barcode: tempData.barcode })
currentComponent.setState({
numberOfRecords: recordCount,
productArray: updatedArray
}
Resources:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push
According to MDN:
The push() method adds one or more elements to the end of an array and returns the new length of the array.
It appears that your code expects that Array.push() will return the modified array itself:
productArray: currentComponent.state.productArray.push(...
To prevent the state corruption you should do construct the new array separately, before invoking setState().
Array's push() function returns integer, so you cannot call map() function on it. Try to change your function to:
currentComponent.setState({
numberOfRecords: recordCount,
productArray: [...currentComponent.state.productArray, {
name: tempData.name,
barcode: tempData.barcode
}]
})
The JavaScript Array.push method does not return the modified array, it returns the new length of the array, which is a number. Numbers in JavaScript do not have the map method.
You need to do first create a clone of the productArray, then push the new data, and finally set state:
const newProductArray = [...currentComponent.state.productArray]
newProductArray.push({
name: tempData.name,
barcode: tempData.barcode
})
currentComponent.setState(
{
numberOfRecords: recordCount,
productArray: newProductArray
}
)
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/push

Why is $httpProvider.interceptors returning an `undefined` value

I've created a basic AngularJS app that consumes Yelp's API and am having trouble using $httpProvider.interceptors to parse my response.
Here is my app:
var app = angular.module("restaurantList", []);
My yelpAPI service (not pictured) authenticates my API request and generates a HTTP request. I then output the data received to the Web Console like so:
app.controller("mainCtrl", ["$scope", "yelpAPI", function ($scope, yelpAPI) {
$scope.restaurants = [];
yelpAPI.get(function (data) {
$scope.restaurant = data;
console.log($scope.restaurant);
});
}]);
Here is data from my request:
Object {region: Object, total: 37, businesses: Array[20]}
I want the array located in the businesses property. So, I figured it would be a good idea to use $httpProvider.interceptors to parse the objects found, in the Object.businesses array.
Here is what $httpProvider.interceptors looked like, when I made my initial request:
app.config(function ($httpProvider) {
$httpProvider.interceptors.push(function () {
return {
response: function (response) {
return response;
}
}
});
});
Here is what $httpProvider.interceptors looks like now:
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
response: function(response) {
var old_response = response.businesses,
new_response = [];
for (var i = 0; i < old_response.length; i++) {
var obj = old_response[i],
new_obj = {
restaurant_name: obj.name,
phone_number: obj.display_phone,
yelp_rating: obj.rating,
reservation_url: obj.reservation_url
};
new_response.push(new_obj);
}
return new_response;
}
}
});
});
Now, I'm receiving an error that says TypeError: Cannot read property 'businesses' of undefined. Is there something I'm overlooking?
EDIT #1
I used console.log(response) inside the interceptor to print my response and found that response.businesses should actually be response.data.businesses. Which resolves my error but now my $http call returns undefined. Any idea what my new problem could be?
EDIT #2
app.factory("yelpAPI", function($http, nounce) {
return {
get: function(callback) {
var method = "GET",
url = "http://api.yelp.com/v2/search";
var params = {
callback: "angular.callbacks._0",
oauth_consumer_key: "my_oauth_consumer_key",
oauth_token: "my_oauth_token",
oauth_signature_method: "HMAC-SHA1",
oauth_timestamp: new Date().getTime(),
oauth_nonce: nounce.generate(),
term: "American",
sort: 2,
limit: 20,
radius_filter: 4000,
deals_filter: true,
actionlinks: true
};
var consumerSecret = "my_consumer_secret",
tokenSecret = "my_token_secret",
signature = oauthSignature.generate(method, url, params, consumerSecret, tokenSecret, {
encodeSignature: false
});
params["oauth_signature"] = signature;
$http.jsonp(url, {
params: params
}).success(callback);
}
}
});
In return angular wait object with {data : }:
app.config(function($httpProvider) {
$httpProvider.interceptors.push(function() {
return {
response: function(res) {
var old_response = res.businesses,
new_response = [];
for (var i = 0; i < old_response.length; i++) {
var obj = old_response[i],
new_obj = {
restaurant_name: obj.name,
phone_number: obj.display_phone,
yelp_rating: obj.rating,
reservation_url: obj.reservation_url
};
new_response.push(new_obj);
}
return {data : new_response};
}
}
});
});
Return as {data : new_response}
Emir helped me resolve this issue but essentially, whenever you use $httpProvider.interceptors you have to update response.data and return the entire response object (i.e. not just a new array, as I did) because $http selects the data property for you.

Firebase retrieve Object by Key in JavaScript Api

Help:
I'm an object of Firebase and can not recover only one item from the list because the key is a objectId and the doc api JS Firebase, it does not have a method to recover for me.
Can you help me?
Controller
var rooms = Rooms.all();
console.log('All Rooms:', rooms);
console.log('Rooms length:', rooms.length);
// New test room
if (!rooms) {
var objRooms = [
{
cc: 'Business 1',
name: 'Chat 1',
city: 'Curitiba',
state: 'PR'
},
{
cc: 'Business 2',
name: 'Chat 2',
city: 'Floripa',
state: 'SC'
}
]
var objRoom = Rooms.save(objRooms);
console.log('ROOMID: ', objRoom.key());
}
Service
.factory('Rooms', function ($firebaseObject) {
// Might use a resource here that returns a JSON array
var ref = new Firebase(firebaseUrl);
var rooms = $firebaseObject(ref.child('rooms'));
return {
all: function () {
return rooms;
},
get: function (roomId) {
// Simple index lookup
console.log('ROOMD:', rooms);
return rooms[ ref.child(roomId) ];
},
save: function (roomData) {
var obj = ref.child('rooms');
var onComplete = function (error) {
if (error) {
console.log('Data could not be saved: ', error);
}
else {
console.log('Data saved successfully!');
}
};
return obj.push(roomData, onComplete);
}
}
})
Output:
Chat Controller initialized!
controllers.js:117 Object {params: Object, current: Object, $current: extend, transition: null}$current: extendcurrent: Objectget: (stateOrName, context)go: go(to, params, options)href: href(stateOrName, params, options)includes: includes(stateOrName, params, options)is: is(stateOrName, params, options)params: ObjectroomId: "-JxlCvzgbdkQfoA1Of78"__proto__: Objectreload: reload()transition: nulltransitionTo: transitionTo(to, toParams, options)__proto__: Object
services.js:78 Selecting the room with id: -JxlCvzgbdkQfoA1Of78
services.js:20 ROOMD: d {$$conf: Object, $id: "rooms", $priority: null}
app.js:43 Logged in as : simplelogin:2
The factory Rooms is a problem:
get: function (roomId) {
// Simple index lookup
console.log('ROOMS:', rooms);
console.log('ROOM specified:', ref.child(roomId).key());
return rooms[ ref.child(roomId) ];
},
[Update]
I created the factory Objects for filter Object data:
.factory('Objects', function () {
return {
filter: function (objectValues, objectKey) {
// to take an action after the data loads, use the $loaded() promise
objectValues.$loaded().then(function () {
// To iterate the key/value pairs of the object, use angular.forEach()
angular.forEach(objectValues, function (value, key) {
if (key === objectKey) {
console.log(objectValues[objectKey]);
return objectValues[objectKey];
}
});
});
}
}
})
and Rooms factory, I edited method get and set:
get: function (roomId) {
return Objects.filter(rooms, roomId);
},
[Update]
I have a database based in the image:
I need list object data.
JavaScript Api
https://www.firebase.com/docs/web/api/
First of all you should use Angularfire which provides some useful methods for using Firebase with AngularJS. You can find the documentation here:
https://www.firebase.com/docs/web/libraries/angular/api.html
Now, your question is how to access an single item using it's key. You can do that simply by just providing the url to that object when retrieving either a $firebaseArray or $firebaseObject (when using Angularfire API):
http://myfirebase.firebase.io/blazing-heat-9118/rooms/ + roomId
And then pass this url to a new Firebase() call:
var ref = new Firebase('http://myfirebase.firebase.io/blazing-heat-9118/rooms/' + roomId);
var room = $firebaseObject(ref);
// To take an action after the data has finished loading, use the $loaded() promise
obj.$loaded().then(function(res) {
console.log(res); // res will be the room object
// To iterate the key/value pairs of the object, use angular.forEach()
angular.forEach(obj, function(value, key) {
console.log(key, value);
});
});
Now you will have fetched the single room from the database.
I'd suggest reading through the Angularfire documentation thoroughly as it contains some great methods for handling your data.

Categories

Resources